[英]Winsock: recv() on Server is blocking, but client has already moved past send()
I am working on a project for school and have run into the following problem.我正在为学校做一个项目,并遇到了以下问题。 My server is blocking out on recv() despite my client already sending its full message.
尽管我的客户端已经发送了完整的消息,但我的服务器在 recv() 上被阻塞了。
This is what I want to happen:这就是我想要发生的事情:
Server Client
recv() <---- send()
send() ----> recv()
This is what is happening:这是正在发生的事情:
Server Client
recv() <---- send()
recv() ----- recv()
Some Background一些背景
2 Weeks ago I created the client by itself with an already coded server application. 2 周前,我使用已经编码的服务器应用程序自行创建了客户端。 When I coded the client it functioned properly with the provided server, so I want to say that the client is wrong, but I don't know how to get the server that I coded to recognize that no more data will be coming in.
当我对客户端进行编码时,它与提供的服务器一起正常运行,所以我想说客户端是错误的,但我不知道如何让我编码的服务器识别不会有更多数据进入。
Code代码
Here is the code that I believe is relevant:这是我认为相关的代码:
Client:客户:
bytesSent = 0;
retVal = send(sock, phrase, msgLen, 0);
bytesSent = retVal;
while (bytesSent < msgLen) {
retVal = send(sock, phrase + bytesSent, msgLen - bytesSent, 0);
if (retVal == SOCKET_ERROR) {
DisplayFatalErr("send() function failed.");
exit(1);
}
bytesSent += retVal;
// May need to re-call send in order to keep sending the data.
}
...
bytesRead = 0;
while (bytesRead < msgLen) {
retVal = recv(sock, rcvBuffer, RCVBUFSIZ - 1, 0);
if (retVal <= 0) {
DisplayFatalErr("recv() function failed.");
exit(1);
}
bytesRead += retVal;
for (int i = 0; i < retVal; i++) {
printf("%c", rcvBuffer[i]);
}
}
Server:服务器:
char* rcvBuffer[RCVBUFSIZ]; // RCVBUFSIZ = 50
char* msg = "";
int bytesRead = 0;
do {
if ((bytesRead = recv(clientSock, rcvBuffer, RCVBUFSIZ - 1, 0)) == 0) {
break;
}
if (bytesRead < 0) {
return -1;
}
char* msgConcatenated;
int msgLen = strlen(msg);
msgConcatenated = malloc(msgLen + bytesRead);
if (msgConcatenated != NULL) {
int newMsgLen = strlen(msgConcatenated);
strncpy_s(msgConcatenated, newMsgLen, msg, msgLen);
strncat_s(msgConcatenated, newMsgLen, rcvBuffer, bytesRead);
msg = msgConcatenated;
}
} while (bytesRead != 0);
Let me know if I need to provide extra information.如果我需要提供额外信息,请告诉我。
When using TCP , to signal the other end of the socket that no more data will be sent, a packet with the FIN flag set must be sent.当使用TCP时,要向套接字的另一端发出不再发送数据的信号,必须发送一个设置了 FIN 标志的数据包。 This is accomplished in Winsock by calling the function
shutdown
with SD_SEND as the second parameter.这在 Winsock 中通过使用 SD_SEND 作为第二个参数调用 function
shutdown
来完成。 This will cause the program on the other end of the socket to no longer block when calling recv
.这将导致套接字另一端的程序在调用
recv
时不再阻塞。 Instead, recv
will return 0 indicating that the connection has been gracefully closed (unless there is data left that has not been read yet).相反,
recv
将返回 0 表示连接已正常关闭(除非还有尚未读取的数据)。 See the Microsoft documentation on the shutdown function for further information.有关详细信息,请参阅有关关闭 function 的 Microsoft 文档。 This documentation page also contains some helpful information about graceful socket closure.
该文档页面还包含一些有关优雅套接字关闭的有用信息。
Also, as has been pointed out in the comments, your code contains a memory leak in the following line:此外,正如评论中所指出的,您的代码在以下行中包含memory 泄漏:
msg = msgConcatenated
In that line, you reassign msg
without first freeing the memory that msg
is pointing to.在该行中,您无需先释放
msg
指向的 memory 就重新分配msg
。 Unfortunately, fixing that memory leak is not easy, because you can't simply call free
on msg
before reassigning it.不幸的是,修复 memory 泄漏并不容易,因为在重新分配之前不能简单地在
msg
上调用free
。 This is because, in the first iteration of the loop, msg
can also be pointing to something else than dynamically allocated memory.这是因为,在循环的第一次迭代中,
msg
还可以指向动态分配的 memory 之外的其他内容。 Therefore, to fix the leak, you would also have to keep track of what type of memory msg
is pointing to, or make it always point to dynamically allocated memory, even when the string is empty (ie when it only contains the terminating null character).因此,要修复泄漏,您还必须跟踪
msg
指向的 memory 类型,或者使其始终指向动态分配的 memory,即使字符串为空(即,它仅包含终止 Z37A6259CC4891DAE02 字符) )。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.