在客户端和服务器程序之间发送和接收消息给我意想不到的结果

Sending and receiving messages between client and server program giving me unexpected result

这是我的服务器程序代码:

...
listen(s , 3);

//Accept and incoming connection
cout<<"\n\nWaiting for incoming connections... ";

int c = sizeof(sockaddr_in);

Socket newSocket = accept(s , (struct sockaddr *)&client, &c);
if (newSocket == INVALID_SOCKET)
{
    cout<<"\nAccept failed with error code : "<<WSAGetLastError();
}

// Since both server and client are now connected, it's time to send and receive players' name

string me;
char other[30];
fi.close(); fi.open("data.dat");
fi>>me; fi.close();

recv(newSocket,other,strlen(other),0);
send(newSocket,me.c_str(),me.length(),0);

cout<<me<<endl<<other;

这是客户端程序代码:

Socket s;
 //Connect to server
if (connect(s , (sockaddr *)&server , sizeof(server)) < 0)
{
    cout<<"\nConnection error.";
    _getch();
    return 1;
}

//reading name and sending it to server
string me;
char other[30];
ifstream fi("cdata.dat");
fi>>me; fi.close();

send(s,me.c_str(),me.length(),0);
recv(s,other,strlen(other),0);

cout<<me<<endl<<other;

假设 data.dat 包含单词 Hero cdata.dat 包含单词 'Zero'

现在服务器端输出是(忽略其他行):

Hero
Zero%$#5^sdj

客户端输出为(忽略其他行):

Zero
He

有什么问题?

您的 'other' 数组长度为 30,但是您没有通过 recv 的 return 值(即已读取的字节数)裁剪该数组的长度.

另外,另一个数组的 strlen 是危险的,因为它不是以 null 结尾的字符串,而是一个恒定大小的数组,您应该使用该数组的长度而不是 strlen。

我相信如果您在客户端中做同样的事情,它也会解决这个问题。另一个数组在未初始化时可能包含一个随机空字节,这将给出一个您不期望的奇数 strlen 值。

您在这里错误地使用了函数strlen。这通过搜索字符 [=14=](空终止符)的第一次出现来确定 c 字符串的长度。鉴于您没有初始化 other 数组,此值将是随机的,而不是您可能期望的 30。

您可以更改代码以明确指定数字 30 作为要接收的最大字节数。您还可以通过将发送的字符串长度加 1 来显式发送空终止符。所以服务器代码变成:

recv(newSocket,other,30,0);
send(newSocket,me.c_str(),me.length()+1,0);

客户端代码变为:

send(s,me.c_str(),me.length()+1,0);
recv(s,other,30,0);

最好还是在 other 声明和上面的 recv 用法中将硬编码的 30 更改为某个整数常量。