[英]Java TCP Client and C# Server; Client Only Receives Message After Server Closes
[英]C# TCP server receives two messages send by Python client at once
我正在嘗試接收由 Python TCP 客戶端發送到 C# 服務器的多條消息。 我確實收到了數據,但是一下子就收到了,我不希望這種情況發生。 我試圖將服務器緩沖區大小設置為我發送的 byte[] 的大小,但它沒有用( source )。 任何想法如何解決這個問題?
客戶端發送代碼:
import socket
def send_to_remote(sock, data):
data_bytes = bytearray()
data_bytes.extend(map(ord, data)) # appending the array with string converted to bytes
bytes_length = len(data_bytes) # length of the array that I am sending
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, bytes_length) # setting the buffer size to the array length
print(bytes_length)
sock.send(data_bytes) # sending the data
服務器接收代碼:
public static string ReadData(TcpClient connection)
{
StringBuilder receivedDataStr = new StringBuilder();
NetworkStream connectionStream = connection.GetStream();
if (connectionStream.CanRead)
{
byte[] connectionBuffer = new byte[connection.ReceiveBufferSize];
Console.WriteLine(">> Reading from NODE");
int bytesRead = 0;
bytesRead = connectionStream.Read(connectionBuffer, 0, 1024);
receivedDataStr.Append(Encoding.ASCII.GetString(connectionBuffer, 0, bytesRead));
Console.WriteLine(">> " + connection.ReceiveBufferSize);
return receivedDataStr.ToString();
}
else
{
Console.WriteLine(">> Can't read from network stream");
return "none-read";
}
}
編輯:
我要做的是:
send_to_remote(socekt, "msg1")
send_to_remote(socekt, "msg1")
進而:
string msg1 = ReadData(client);
string msg2 = ReadData(client);
我收到 106200 的緩沖區數組。
結果是:
"msg1 (then new line) msg2"
"" (string msg2 is waiting for data)
先感謝您!!
TCP 是流協議,而不是數據包協議。 絕對不能保證您會以與發送的完全相同的塊獲取數據 - 所有保證的是您將以正確的順序獲取字節(或失敗或超時等) . 您可以單獨獲取每個字節,或一次獲取 14 條消息。 或者介於兩者之間的任何內容,包括一次接收消息的一半,以及下一次接收消息的另一半。 在 unicode(等)的情況下,這也意味着單個字符可以拆分為多個接收。
任何基於 TCP 的多消息協議都需要包含某種框架,即某種讓您知道每個單獨消息的開始和結束位置的方法。 由於您使用的是基於文本的協議,因此一個常見的選擇是使用 CR、LF 或 CR+LF 分隔邏輯消息 - 然后緩沖數據直到您擁有完整的消息 - 通過查找行結束。 為了完整性:在二進制協議的情況下,通常使用某種指示有效載荷中數據量的標頭對有效載荷進行長度前綴,然后您只需要解析標頭,確定長度並緩沖,直到您有那么多數據。
在具有文本協議且沒有挑戰性可擴展性問題的簡單應用程序中,可以使用StreamReader
(在NetworkStream
之上)為您完成該部分,然后只需使用ReadLine
或ReadLineAsync
。 但是請注意,這在“真實”服務器(尤其是ReadLine
)中是一個壞主意 - 您不希望惡意或只是有問題的客戶端永遠鎖定線程,因為它發送了幾個沒有行結尾的字符,然后沒有發送任何其他東西......從來沒有。 當然,在一個嚴肅的服務器,你就不會使用每個客戶端線程反正。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.