簡體   English   中英

使用TCP套接字發送數據時是否必須對大數據進行分塊?

[英]Do I have to chunk large data while sending it with tcp socket?

我通過TCP套接字發送一些不大字符串。 今天,我發送2031個字節,而接收端卻一無所獲(我已經發送了更大的消息-在2040個字節之前到幾天前)-這還不是很糟糕,程序知道出了點問題,然后再次發送數據(第三次嘗試成功)。 現在,我想知道是否應該將消息拆分為較小的塊並在循環語句中發送它們? 我的代碼中是否缺少某些內容?

Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,0);
sock.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket,SocketOptionName.SendTimeout,0);           
LingerOption lingerOption = new LingerOption (true, 1); 
sock.SetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket,SocketOptionName.Linger, lingerOption );
sock.Blocking =  true;

try
{
    sock.Connect(_dostHostEp);
}
catch(SocketException e)                     
{                                       
    sock.Close();
    throw new Exception("Connection error (" + _dostHostEp.Address + ":" + _dostHostEp.Port + ")" + e.Message);             
}

try    
{
    sock.Send(Encoding.UTF8.GetBytes(message));                             
}
catch(SocketException e)
{                   
    sock.Close();               
    throw new Exception("Error while sending message to (" + _dostHostEp.Address + ":" + _dostHostEp.Port + ")" + e.Message);               
}

為什么要堅持將2031字節分成一個塊? 相反,您必須在接收方讀取數據, 直到數據存在。 這意味着,例如,您讀取了一個1800字節的塊,另一個231字節的塊,然后讀取了0字節,這意味着數據結束。

我一直考慮在沒有明確定義結束字符的情況下發送數據是一種不好的做法。 我個人建議執行以下操作:

作為發件人,在郵件前添加STX字符(0x02),並附加ETX字符(0x03)。

接收者應將STX識別為新消息的開始,然后讀取(阻止?),直到接收到ETX。 如果在合理的時間內未收到任何ETX,則說明讀取整個消息時出現問題。

您不需要使用STX和ETX,也可以使用\\ r \\ n或不屬於消息本身的任何內容。

如果您沒有使用定義良好的消息結尾,則讀者將永遠不知道何時停止閱讀,並且會弄亂您的交流。

我確定有問題的一個示例案例:

發送者一個接一個地發送兩個消息。 如果沒有EndOfMessage字符,則接收方將嘗試將其作為一條消息讀取。 借助EOM,接收方可以拆分兩個消息並同時處理它們。

暫無
暫無

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

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