簡體   English   中英

Winsock:服務器上的 recv() 被阻塞,但客戶端已經移過 send()

[英]Winsock: recv() on Server is blocking, but client has already moved past send()

我正在為學校做一個項目,並遇到了以下問題。 盡管我的客戶端已經發送了完整的消息,但我的服務器在 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);

如果我需要提供額外信息,請告訴我。

當使用TCP時,要向套接字的另一端發出不再發送數據的信號,必須發送一個設置了 FIN 標志的數據包。 這在 Winsock 中通過使用 SD_SEND 作為第二個參數調用 function shutdown來完成。 這將導致套接字另一端的程序在調用recv時不再阻塞。 相反, recv將返回 0 表示連接已正常關閉(除非還有尚未讀取的數據)。 有關詳細信息,請參閱有關關閉 function 的 Microsoft 文檔 該文檔頁面還包含一些有關優雅套接字關閉的有用信息。

此外,正如評論中所指出的,您的代碼在以下行中包含memory 泄漏

msg = msgConcatenated

在該行中,您無需先釋放msg指向的 memory 就重新分配msg 不幸的是,修復 memory 泄漏並不容易,因為在重新分配之前不能簡單地在msg上調用free 這是因為,在循環的第一次迭代中, msg還可以指向動態分配的 memory 之外的其他內容。 因此,要修復泄漏,您還必須跟蹤msg指向的 memory 類型,或者使其始終指向動態分配的 memory,即使字符串為空(即,它僅包含終止 Z37A6259CC4891DAE02 字符) )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM