在客户端-服务器通信c++中接收到垃圾值

Garbage value received in client server communication c++

本文关键字:客户端 服务器 通信 c++      更新时间:2024-09-22

我试图在windows上编写一个简单的客户端-服务器程序。我的服务器端代码如下所示。

#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int main()
{
WSADATA WSAData;
SOCKET serverSock, clientSock;
SOCKADDR_IN serverAddr, clientAddr;
WSAStartup(MAKEWORD(2,0),&WSAData);
serverSock=socket(AF_INET,SOCK_STREAM,0);
serverAddr.sin_addr.s_addr=INADDR_ANY;
serverAddr.sin_family=AF_INET;
serverAddr.sin_port=htons(5555);
bind(serverSock,(SOCKADDR *)&serverAddr, sizeof(serverAddr));
listen(serverSock,0);
std::cout<<"Listening for incoming connections n";
char buffer[1024];
//memset(buffer,0,sizeof(buffer));
int clientAddrsize= sizeof(clientAddr);
if(clientSock = ( accept(serverSock,(SOCKADDR *)&clientAddr, &clientAddrsize ) != INVALID_SOCKET) )
{
std::cout<<"Client connected n";
recv(clientSock,buffer,int(strlen(buffer)),0);
std::cout<<"Client Says: " << buffer <<"n" ;
Sleep(10000);
//memset(buffer,0,sizeof(buffer));
closesocket(clientSock);
closesocket(serverSock);
WSACleanup();
}
return 0;
}

客户端代码看起来像:

#include <iostream>
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int main()
{
WSADATA WSAData;
SOCKET clientSock;
SOCKADDR_IN addr;
WSAStartup(MAKEWORD(2,0),&WSAData);
clientSock=socket(AF_INET,SOCK_STREAM,0);
addr.sin_addr.s_addr=inet_addr("127.0.0.1");
addr.sin_family=AF_INET;
addr.sin_port=htons(5555);
connect(clientSock,(SOCKADDR *)&addr,sizeof(addr));
std::cout <<"Connected to the server n";
//memset(buffer,0,sizeof(buffer));
char buffer[1024]={'h','e','l','l','o','.',''};
send(clientSock,buffer,int(strlen(buffer)),0);
std::cout<<"Message sent n" ;
Sleep(10000);
closesocket(clientSock);
WSACleanup();
std::cout<<"Socket closed n";
return 0;
}

我在服务器端看到以下输出:

Listening for incoming connections
Client connected
Client Says: R☺

我所期待的是Client Says: Hello.。不知道我为什么得到垃圾值。

感谢

char buffer[1024];

这在自动作用域中声明了一个本地char数组。数组没有初始化任何内容,并且包含随机垃圾。

recv(clientSock,buffer,int(strlen(buffer)),0);

这将传递bufferstrlen。然而,buffer包含垃圾,这是未定义的行为,最终结果可能是随机的,介于此时的立即崩溃或strlen的某个奇怪的返回值之间。

此外,recv的返回值被完全忽略,根本不检查

所有套接字系统调用都可能失败,每个套接字系统调用sendrecv和所有其他调用都可能失效。此外,即使它成功了,recv也不能保证在一次拍摄中send的所有内容都将在一次摄影中被recv编辑。

例如,如果send发送了10个字节,则对recv的第一个调用可能返回1或5,表明只有前一个或五个字节立即为recv。您不能保证recv将同时接收这10个字节。否则,recv将(显然(需要再次被调用以接收消息的其余部分。

您需要解决所有这些问题,才能拥有可靠的客户端/服务器应用程序:

  1. 检查所有系统调用的返回值。我所说的关于recv的一切也适用于send。尝试send10个字节可能会返回7,表示只发送了前7个字节,然后您必须实现适当的逻辑来发送剩余的字节。

  2. 修复未定义的行为,将未初始化的值传递给strlen