簡體   English   中英

Java-> C ++ TCP套接字直到關閉才發送

[英]Java -> C++ TCP Socket does not send until close

我面臨另一個TCP套接字問題。 我已經閱讀了很多問題,並回答了類似問題,但是我的問題有所不同。

我有一個Java客戶端和C ++服務器。 一切都按預期進行,直到我使用不同的機器為止(到目前為止,它還等同於其他問題)來自客戶端的消息似乎卡在了TCP緩沖區中。 當我最后關閉套接字時,所有內容都發送到了服務器。 但是這些單個消息是控制消息,因此我需要立即發送它們。 據我所知,這是預期的行為,但是如何發送可靠的控制消息。

有沒有一種方法可以強制發送消息。 (我可以將套接字打開幾分鍾,不發送任何消息。)

有什么不對? (請參見以下代碼)

每次執行一次真正的沖洗時,我都必須關閉插座嗎?

我應該使用UDP協議,還是需要額外的協議工作量?

Javacode:

mSocketSend = new Socket();
mSocketSend.connect(new InetSocketAddress(mServerIp, mSocketPortSend), mTimeOut);
PrintWriter pw = new PrintWriter(mSocketSend.getOutputStream(), true);
pw.println(data);

C ++代碼:

   opening socket...(i leave that)
   char* buffer = new char[1024];
   int rc = recv(mConnectedSocket, buf, 1024, 0);

如果您想要更多。 寫下來。 我幾乎遺漏了一切。 ^^我認為它不相關。 通常,通訊進行得很好。 所以這只是這個TCPBuffer事情。

我知道應該有一些定界符或消息長度的東西。 但實際上:未發送的消息長度沒有幫助。 ^^

謝謝你的幫助。

編輯#01整個代碼:

mSocket->createSocketServer(22);
    char* buffer = new char[1024];
 while(true){

        int numberBytes = mSocket->receiveChars(buffer, 1024);

        if (numberBytes > 0){
            uninterestingHandlingFunction(buffer);
        }else{
            mSocket->createSocketServer(22);
        }
    }

bool Socket::createSocketServer(u_short port)
{
    if (mConnectedSocket != INVALID_SOCKET)
    {
        closesocket(mConnectedSocket);
    }

    if (s == INVALID_SOCKET)
    {
        WSADATA wsa;

        if (WSAStartup(MAKEWORD(2,0), &wsa) != 0)
            return 0;

        s = socket(AF_INET, SOCK_STREAM, 0);
        if (s == INVALID_SOCKET)
            return 0;

        SOCKADDR_IN addr;
        memset(&addr, 0, sizeof(SOCKADDR_IN));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);
        addr.sin_addr.s_addr=ADDR_ANY;

        if (bind(s, (SOCKADDR*)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
        {
            s = INVALID_SOCKET;
        } else if (listen(s, 10) == SOCKET_ERROR)
        {
            s = INVALID_SOCKET;
        }

        if (s == INVALID_SOCKET)
        {
            closesocket(s);
            return 0;
        }
    }
    mConnectedSocket = accept(s, NULL, NULL);

    if (mConnectedSocket == INVALID_SOCKET)
    {
        closesocket(s);
        return 0;
    }
    return 1;
}

int Socket::receiveChars(char* buf, unsigned maxSize)
{
    if (mConnectedSocket == INVALID_SOCKET)
        return -1;

    int rc = recv(mConnectedSocket, buf, maxSize, 0);
    if (rc == SOCKET_ERROR)
    {
        std::cout << "Socket: error " << WSAGetLastError() << std::endl;
    }
    return rc;
}

你想要...

編輯#2再試一次

我嘗試了幾件事。 首先:每次通過真實網絡連接的設備上都不會發生此問題。 ->完全重新啟動客戶端和服務器->不會出現問題->完全重新啟動客戶端和服務器->出現問題

可悲的是,我不知道該養成什么樣。

我偶然發現的另一件事是bind和listen套接字(在Code SOCKET中)。 該套接字偵聽連接,並且如果工作線程需要一個新的連接(啟動時或前一個關閉),則套接字s將下一個排隊的連接提供給mConnectedSocket進行接收,其他連接將在處理一個時積壓。 從Java視圖:連接了一個套接字(設備A)。 下一個套接字(設備B)嘗試連接。 ->連接成功(如果確實發生,則可以通過代碼正確控制)->然后以自然狀態發送數據。 (套接字仍在c ++方面的積壓中)

好吧,這很難轉化為我所經歷的習慣。 我會盡力表達自己的想法。 Javaside:PrintWriter已創建。 饋入數據並被刷新。 因為未完全建立連接(C ++側沒有其他的connectedSocket)。 沖洗不起作用。 並且onClose套接字最終刷新其內容。

如果您認為這樣,請告訴我閉嘴。 我真的不知道“連接積壓”在實現中實際上是什么意思。

我知道,我應該為每個連接打開一個新線程,但目前無法。 因此,請堅持使用此服務器代碼。

您需要執行flush(),將數據推出。

PrintWriter.flush();

或者使用帶有自動沖洗功能的寫入器。

您還應該確保服務器讀取一行(直到\\ n),而不是整個1024個字符,但是我不知道recv()的作用,所以我也不知道。

修復。 有點尷尬...我在編輯中發現積壓的確是問題所在。 如果同時有兩個客戶端連接到服務器,則第二個客戶端將被積壓,並且當第一個客戶端斷開連接時,將處理他的消息。

另外(線索來了)

如前所述,它是一個android java客戶端。 在Java端還有另一個線程可以從C ++服務器接收數據。 此套接字連接到另一個端口。 但是我在設置活動中設置了要連接的端口和ip地址,並且另一個套接字的默認端口有一個錯誤的端口(與issuescket相同,使用了錯誤的變量),因此,此套接字先連接,issuescket連接到積壓。 僅當我輸入設置以設置另一個IPAddress時,才使用此默認值(例如,當我連接到遠程主機而不是localhost時)

令人難以置信的情況...我什至沒有寫設置...

WIRESHARK將解決此問題。

PrintWriter pw = new PrintWriter(mSocketSend.getOutputStream(), true);
pw.println(data);
pw.flush();

當您使用自動刷新,甚至嘗試使用顯式flush()

可能是因為您沒有打開inputStream。 嘗試也執行getInputStream()

否則,您是否嘗試過:

  1. 您不使用connect而是僅在Socket構造函數中直接提供參數的任何差異?

  2. setTcpNoDelay上的setTcpNoDelay (雖然不會造成幾分鍾的延遲!)?

實際上,您的問題可能在接收端, recv必須處於循環狀態(您可以在Google上搜索此示例)。 不能保證每次調用recv不會得到多少。 如果您知道要刷新Java站點上的數據,則可能是您的問題。

您的循環編碼錯誤。 每個新的recv()都會覆蓋前一個。 您應該提前offset參數。

暫無
暫無

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

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