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

时间:2016-06-20 15:44:30

标签: c++ windows winsock2

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

...
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包含“零”字样

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

Hero
Zero%$#5^sdj

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

Zero
He

有什么问题?

2 个答案:

答案 0 :(得分:1)

您在此处错误地使用了strlen功能。这通过搜索第一次出现的字符c(空终止符)来确定\0 - 字符串的长度。鉴于您没有初始化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);

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

答案 1 :(得分:0)

你的其他&#39;数组的长度为30,但是不要使用recv的返回值来剪切该数组的长度,这是读取的字节数。

另外,另一个数组的strlen是危险的,因为它不是一个空终止字符串而是一个常量大小的数组,你应该使用这个数组的长度而不是strlen。

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