【发布时间】:2019-10-11 21:52:42
【问题描述】:
我正在为学校做一个项目,但遇到了以下问题。尽管我的客户端已经发送了完整的消息,但我的服务器在 recv() 上被阻塞了。
这就是我想要发生的事情:
Server Client
recv() <---- send()
send() ----> recv()
这是正在发生的事情:
Server Client
recv() <---- send()
recv() ----- recv()
一些背景
2 周前,我使用已编码的服务器应用程序自行创建了客户端。当我对客户端进行编码时,它与提供的服务器一起正常运行,所以我想说客户端是错误的,但我不知道如何让我编码的服务器认识到不会有更多数据进入。
代码
这是我认为相关的代码:
客户:
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]);
}
}
服务器:
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);
如果我需要提供额外信息,请告诉我。
【问题讨论】:
-
关于:
int msgLen = strlen(msg);因为 char 数组msg没有被设置为任何东西,尤其是任何以 NUL 终止字节结尾的东西,结果是未定义的行为,它可能导致任何东西,包括段故障事件 -
关于:
msgConcatenated = malloc(msgLen + bytesRead);这会导致内存泄漏,因为原始指针被覆盖(因此永远丢失)强烈建议使用realloc() -
请发minimal reproducible example,以便我们重现问题并帮助您调试。
-
关于:
bytesRead += retVal; for (int i = 0; i < retVal; i++) { printf("%c", rcvBuffer[i]);为什么不断重复输出部分消息?建议全部接收后才输出数据 -
@user3629249:我没有看到
int msgLen = strlen(msg)的未定义行为,因为在第一次迭代中,msg指向一个空字符串,在进一步的迭代中,它指向最后一个连接的字符串。但是,您是对的,代码包含memory leak。但是你提到的那一行并没有发生内存泄漏,因为msgConcatenated已经保存在msg中。相反,内存泄漏发生在msg = msgConcatenated行中,因为msg之前指向的内存不再被任何变量引用。