字符串变量和char变量 cout 不止一次。我有 ZeroMem()buff 我该如何对其进行归一化,以便引用“ Invader Said:RedditInvader Reddit”的“ Invader Said:Reddit”。
char buff[4096];
string serverMessage = "GET OUT MY SERVER!";
while (true) {
ZeroMemory(buff, 4096);
int bytesRecived = recv(clientSocket, buff, 4096, 0);
if (bytesRecived == SOCKET_ERROR) {
cerr << "Error in recv()! Qutting!" << endl;
}
if (bytesRecived == 0) {
cout << "Client Disconnected" << endl;
break;
}
cout << "Invader Said: " << buff;
send(clientSocket, (char*)serverMessage.c_str(), serverMessage.length(), 0);
}
答案 0 :(得分:1)
不能保证对方发送的所有字符都将在一条消息中发送。因此在PuTty端,当用户键入Reddit
return 时,我们不完全知道所有这些数据将如何通过网络发送。
您的屏幕截图看起来与您的叙述有所不同,因为它们不是第二次Reddit:
Invader said: RedditInvader said:
这是我基于此了解的内容。
在第一个循环中:
if
正文未执行if
主体。 Invader said:
,然后打印收到的字符Reddit
循环继续。在第二次迭代中:
if
正文不会被执行if
主体不被执行。 Invader said:
,然后打印收到的字符,看起来像换行符我无法告诉更多信息(断点?或recv()
仍在等待,因为您没有 Ctrl + D ?...)
这是唯一的解释。如果您将一次收到所有PuTty字符,则会得到不同的输出:
Invader said: Reddit
Invader said: (or something else, but on a new line)
备注1:它与您的问题无关,但如果遇到错误,则程序将继续尝试打印输出和循环,因为在这种情况下您没有预见到break
< / em>
注释2:它也没有链接,但是如果您一次收到正好为4096个字符,则输出可能会导致UB,因为缓冲区末尾会缺少空终止符 >
可能会让您感兴趣:
答案 1 :(得分:1)
您正在将buff
视为终止为空的字符串,但是套接字数据并非终止为空。如果发生恰好接收4096个字节,则operator<<
的使用将超出数组的范围。使用recv()
时,必须考虑buff
的返回值。
与send()
相同。它可能返回的字节数少于请求的字节数,因此您必须查看返回值,并可能不得不再次调用它以重新发送更多数据。
尝试以下方法:
char buff[4096];
const string serverMessage = "GET OUT MY SERVER!";
bool keepLooping = true;
while (keepLooping) {
int bytesRecived = recv(clientSocket, buff, 4096, 0);
if (bytesRecived == SOCKET_ERROR) {
cerr << "Error in recv()! Qutting!" << endl;
break;
}
if (bytesRecived == 0) {
cout << "Client Disconnected" << endl;
break;
}
cout << "Invader Said: ";
cout.write(buff, bytesRecived);
cout << endl;
const char *ptr = serverMessage.c_str();
size_t len = serverMessage.length();
do {
int bytesSent = send(clientSocket, ptr, len, 0);
if (bytesSent == SOCKET_ERROR) {
cerr << "Error in send()! Qutting!" << endl;
keepLooping = false;
break;
}
ptr += bytesSent;
len -= bytesSent;
}
while (len > 0);
}