![](/img/trans.png)
[英]How to send java byte[] on tcp socket to c++ char[] on server?
[英]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()
。
否則,您是否嘗試過:
您不使用connect
而是僅在Socket
構造函數中直接提供參數的任何差異?
setTcpNoDelay
上的setTcpNoDelay
(雖然不會造成幾分鍾的延遲!)?
實際上,您的問題可能在接收端, recv
必須處於循環狀態(您可以在Google上搜索此示例)。 不能保證每次調用recv
不會得到多少。 如果您知道要刷新Java站點上的數據,則可能是您的問題。
您的循環編碼錯誤。 每個新的recv()都會覆蓋前一個。 您應該提前offset參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.