Нужно ли разбивать большие данные на части при отправке через tcp-сокет? - PullRequest
0 голосов
/ 03 ноября 2011

Я посылаю некоторые не большие строки через сокет TCP.Сегодня я отправил 2031 байт, а принимающая сторона не получила все это (я отправил большие сообщения - до 2040 байт несколько дней назад) - это не так уж и плохо, программа знала, что что-то не так, и отправила данные снова (3-я попытка прошла успешно).Теперь мне интересно, если я должен разделить сообщение на более мелкие куски и отправить их в заявлении циклаЕсть ли что-то в моем коде, что я пропускаю?

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

Ответы [ 2 ]

0 голосов
/ 03 ноября 2011

Я всегда считал отправку данных без четко определенного конечного символа плохой практикой. Я лично рекомендовал бы сделать следующее:

В качестве отправителя добавьте к сообщению символ STX (0x02) и добавьте символ ETX (0x03).

Получатель должен распознать STX как начало нового сообщения и затем читать (блокировать?) До получения ETX. Если ETX не был получен в разумные сроки, возникла проблема с чтением всего сообщения.

Вам не нужно использовать STX и ETX, вы также можете использовать \ r \ n или что-то, что не является частью вашего сообщения.

Если вы не используете четко определенный конец сообщения, читатель никогда не узнает, когда прекратить чтение, и вы испортите ваше общение.

Один пример, который я назвал проблемным:

Отправитель отправляет два сообщения одно за другим. Без символа EndOfMessage получатель попытается прочитать это как одно сообщение. С помощью EOM получатель может разделить два сообщения и обработать их оба.

0 голосов
/ 03 ноября 2011

Почему вы настаиваете на получении 2031 байта за один кусок?Скорее, вам придется читать данные на приемной стороне , пока данные не существуют.Это означает, что, например, вы читаете порцию из 1800 байтов, другую порцию из 231 байта, а затем 0 байтов, что означает конец данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...