这是我的服务器程序代码:
...
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
有什么问题?
答案 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值。