Как я могу сказать, Когда Сокет Разъединился

Я использую ElSSLSocket от C#. Это - сокет SecureBlackBox. SecureBlackBox является сторонней библиотекой для обработки защищенных сокетов.

Я вижу, что объект ElSSLSocket имеет свойство под названием 'Сокет', таким образом, базовый сокет является нормальным сокетом.NET.

Мой вопрос, там некоторое событие, которое я могу подписать на то, так, чтобы я видел, когда сокет разъединяется грязно? У меня есть клиент-серверное соединение, которое часто будет разъединяться. Трудно видеть - ли это клиент или сервер, и трудно видеть фактическую причину.

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

Я должен также сообщить, что разъединения, которые я получаю, являются этой ошибкой,

SocketException - Существующее соединение было насильственно закрыто удаленным хостом

ErrorCode - 10054

Если был какой-либо способ, которым я мог на самом деле найти причину этого?

5
задан peter 22 June 2010 в 03:56
поделиться

3 ответа

Обнаружение полуоткрытых соединений является одним из классические сценарии программирования сокетов . Свойство Socket.Connected совершенно бесполезно, а Socket.Poll работает не во всех ситуациях. Лучше всего отправлять «сердцебиение» каждые несколько секунд.

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

4
ответ дан 14 December 2019 в 08:42
поделиться

Я обнаружил, что это работает достаточно хорошо:

Получение

_socket.Poll(100, SelectMode.SelectRead) && _socket.Available == 0

Отправка

!_socket.Poll(100, SelectMode.SelectWrite)
1
ответ дан 14 December 2019 в 08:42
поделиться

Хотя это написано на C , вы должны иметь возможность делать то же самое на C # :

int dummy;
// since you're just testing if the socket is still open for reading you don't
// want it to block, or remove data from the sockets recv buffer
int ret = recv(sockfd, &dummy, sizeof dummy, MSG_DONTWAIT | MSG_PEEK);

if ( ( ret == -1 && ( errno == EAGAIN || errno == EWOULDBLOCK ) )
      || ret > 0 ) {

    // socket is still open for reading

else if ( ret == 0 ) { 

    // socket went through orderly shutdown and is closed for reading

} else {

    // there is some error and the socket is likely closed
    // check errno

}

Допустим, вы думаете, что это половина закрыто, и у вас все еще есть данные, которые вы хотите записать.

int myData = 0xDEADBEEF;
int ret = send(sockfd, myData, sizeof myData, MSG_NOSIGNAL);

Таким образом, если сокет полностью закрыт, ваша отправка не уничтожит вашу программу с помощью SIGPIPE . Вместо этого вызов просто вернет -1 и установит errno в EPIPE .

2
ответ дан 14 December 2019 в 08:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: