简体   繁体   中英

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

I'm sending some not to large strings over tcp socket. Today I send 2031 bytes and receiving end didn't get it all (I've send bigger messages - before 2040 bytes to days ago) - this isn't all that bad, program knew that something was wrong and send the data again (3rd try was successfull). Now I'm wondering if I should split message into smaller chunks and send them in loop statement? Is there something in my code that I'm missing?

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);               
}

Why do you insist to get the 2031 bytes in one chunk? Rather, you'd have to read the data at the receiver side until data exists. This means that for example you read a chunk of 1800 bytes, another chunk of 231 bytes and then 0 bytes which means end of the data.

I've always considered sending data without a well defined end character bad practice. I would personally recommend doing the following:

As the sender, prepend the message with an STX-Character (0x02) and append the ETX-Character (0x03).

The receiver should recognize STX as the start of a new message and then read (blocking?) until an ETX is received. If no ETX is received in reasonable time, there was a problem reading the entire message.

You don't need to use STX and ETX, you might also use \\r\\n or anything that is not part of your message itself.

If you do not use a well defined end of message, the reader will never know when to stop reading and you will mess up your communication.

One sample case I've indentified as problematic:

The sender sends two messages one after the other. Without an EndOfMessage-character, the receiver will try to read this as one single message. With an EOM, the receiver can split the two messages and handle them both.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM