C# сокет игнорирует мое значение SendTimeout - PullRequest
1 голос
/ 07 мая 2020

У меня Socket в приложении C#. (приложение действует как сервер)

Я хочу установить тайм-аут при отправке передачи. Если уровень TCP не получает подтверждение для данных в течение 10 секунд, сокет должен генерировать исключение, и я закрываю все соединение.

 // Set socket timeouts
 socket.SendTimeout = 10000;

//Make A TCP Client
_tcpClient = new TcpClient { Client = socket, SendTimeout = socket.SendTimeout };

Затем позже в коде я отправляю данные этому socket.

    /// <summary>
    /// Function to send data to the socket
    /// </summary>
    /// <param name="data"></param>
    private void SendDataToSocket(byte[] data)
    {
        try
        {              
            //Send Data to the connection           
            _tcpClient.Client.Send(data);              
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Error writing data to socket: " + ex.Message);
            //Close our entire connection
            IncommingConnectionManager.CloseConnection(this);
        }
    }

Теперь, когда я тестирую, я позволяю своим сокетам подключаться, все в порядке. Затем я просто убиваю другой сокет (TCP закрывается, просто выключаю устройство)

Я пытаюсь отправить ему сообщение. Это не тайм-аут? Даже через 60 секунд он все еще ждет.

Я что-то сделал здесь не так, или я неправильно понимаю функциональность установки значения SendTimeout сокетов?

1 Ответ

1 голос
/ 08 мая 2020

Сокет send () фактически выполняет операцию копирования ваших данных в исходящий буфер стека сети. Если копирование выполнено успешно (т. Е. Достаточно места для приема ваших данных), ошибка не генерируется. Это не означает, что другая сторона получила это или даже что данные вышли на провод.

Любой тайм-аут отправки начинает отсчет, когда буфер заполнен , указывая, что другая сторона получение данных медленнее, чем вы их отправляете (или, в крайнем случае, не получаете вообще ничего, потому что кабель сломан, или он был отключен или разбился без надлежащего закрытия своего гнезда). Если полный буфер сохраняется в течение секунд ожидания, вы получите сообщение об ошибке.

Другими словами, нет способа обнаружить резкую ошибку сокета (например, плохой кабель, отключение питания или отказ однорангового узла), другое чем переполнение исходящего буфера для срабатывания тайм-аута.

Обратите внимание, что в случае плавного завершения работы однорангового сокета ваш сокет будет знать об этом и выдать вам ошибки , если вы попытаетесь отправить или получить после того, как условие было получено в вашем сокете , что может занять много микросекунд после завершения операции. Опять же, в этом случае вы должны вызвать ошибку (путем отправки или получения), это не происходит само по себе.

...