Сокет C # TCP получает часть данных о медленном сотовом сетевом соединении, пока соединение еще не разорвано

#c# #sockets

#c# #сокеты

Вопрос:

Я использую консольное приложение в качестве сервера в Windows 10 Pro. Приложение для Android, созданное с использованием движка Unity в качестве клиента. Для обоих приложений я использую сокет TCP на.Net framework.

Примечание: сервер всегда работает по проводному соединению.

Все работает довольно хорошо как на проводных, так и на Wi-Fi-соединениях без проблем, независимо от длины пакета.

Проблема

Каждый вечер сотовая сеть становилась слишком плохой, и клиентское приложение получало только часть данных, когда объем данных немного превышал 50 КБ

Код на стороне сервера:

 _socket.Send(Encoding.ASCII.GetBytes(s));
 

_socket: является экземпляром System.Net.Sockets.Сокет.

s: является строкой.

Код на стороне клиента:

 public static void ReceiveData()
{ 
    message = string.Empty;
    _socket.BeginReceive(globalBuffer, 0, globalBuffer.Length, SocketFlags.None, ReceiveCallBack, null);
}
public static void ReceiveCallBack(IAsyncResult ar)
{
    int internalBuffer = _socket.EndReceive(ar);
    byte[] subtractedBuffer = new byte[internalBuffer];
    Array.Copy(globalBuffer, subtractedBuffer, internalBuffer);
    string stmp = Encoding.ASCII.GetString(subtractedBuffer);
    message  = stmp;

    while (message.Contains("</Cargo>"))
    {
       string stringOne = message.Substring(0, message.IndexOf("</Cargo>")   "</Cargo>".Length);
       string stringLeft = message.Substring(message.IndexOf("</Cargo>")   "</Cargo>".Length);
       message = stringLeft;

       Thread thread = new Thread(TreatOrder);
       thread.Start(stringOne);
    }

    if (!(_socket.Poll(1000, SelectMode.SelectRead) amp;amp; _socket.Available == 0))
    {
        NetWorkScript.LastConnectedTime = DateTime.Now;
        _socket.BeginReceive(globalBuffer, 0, globalBuffer.Length, SocketFlags.None, ReceiveCallBack, null);
    }
    else
    {
      Debug.log("Connection lost");
    }   
}
 

Что я заметил:

Следующая строка кода так и не была выполнена

 else
{
   Debug.log("Connection lost");
}  
 

Сервер продолжает получать сообщения от клиента в том же экземпляре сокета другим потоком, и именно так стало известно, что соединение не разорвано, если только TCP-соединение не может быть разорвано только одним способом.

Что я понимаю до сих пор

TCP гарантирует, что пакеты будут поступать в точном порядке.

Следующая строка кода в моем серверном приложении завершает свою ответственность, и операционная система продолжит миссию по отправке данных.

 _socket.Send(Encoding.ASCII.GetBytes(s));
 

Что меня смущает

Как операционная система будет доставлять данные клиенту?, почему он не продолжает попытки до отправки всех данных, если соединение все еще существует?

Должен ли я создать свой собственный протокол и отправить небольшой пакет, а затем повторно передать, если клиент не подтвердит получение пакета?

Комментарии:

1. «Почему он не продолжает попытки, пока не отправит все данные, если соединение все еще существует?» — Откуда вы знаете, что это не так?

2. Поскольку клиент не получает больше пакетов

3. Как вы это измеряете?

4. буфер получателя в моем клиентском приложении все еще не заполнен [1024]

5. Однако это не означает, что сервер не повторяет попытку. Это просто говорит о том, что они никогда не доставляются успешно.