То, как я могу проверить, является ли (TCP) сокет (скидка), соединилось в C#?

Другое решение, которое я нашел (особенно полезно, если вы хотите установить глобальное поведение), заключается в использовании метода $.ajaxsetup() вместе с свойством statusCode . Как и другие указатели, не используйте код статуса перенаправления (3xx), вместо этого используйте код статуса 4xx и обрабатываете клиентскую сторону с переадресацией.

$.ajaxSetup({ 
  statusCode : {
    400 : function () {
      window.location = "/";
    }
  }
});

Замените 400 кодом состояния вы хотите справиться. Как уже упоминалось 401 Unauthorized, может быть хорошей идеей. Я использую 400, поскольку он очень неспецифичен, и я могу использовать 401 для более конкретных случаев (например, неправильные учетные данные). Поэтому вместо перенаправления непосредственно ваш backend должен возвращать код ошибки 4xx, когда время ожидания сеанса и вы обрабатываете клиентскую часть перенаправления. Работает идеально для меня даже с фреймворками, такими как backbone.js

34
задан Hosam Aly 7 February 2009 в 07:02
поделиться

3 ответа

Смерть сокета изменяет свое поведение несколькими способами, таким образом, эти методы оба действительны :)

С обоими методами Вы на самом деле проверяете те части поведения сокета, которые изменяются после разъединения.

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

TCP надежный протокол, который означает, что каждый пакет, который Вы отправляете, должен быть подтвержден. Подтверждение подразумевает отправку пакетов с ACK набор битов. Эти пакеты могут или не могут содержать дополнительный (полезная нагрузка) данные.

то, Когда сокет подключен, Receive(), заблокируется, пока сокет не получит пакет с непустой полезной нагрузкой. Но когда сокет разъединяется, Receive() возвратится, как только последнее ACK пакет прибывает.

Вызов Receive() гарантирует, чтобы Вы или получили , что в последний раз ACK пакет от Вашей удаленной конечной точки или тайм-аута разъединения происходит, и Вы сможете к [1 119], получают ничто больше на этом сокете.

пример на той же странице показывает, как сделать это. (Интересно, почему это выделяет 1 массив байтов, даже при том, что это звонит, Отправляют с 0 длинами?), Но в сообщении Ian Griffiths говорится, что я должен читать из сокета, не отправляют через него.

, Когда send() луг к сокету, Вы на самом деле пытаетесь добавить некоторые данные в конец очереди сокета. Есть ли существует некоторое место, покинутое в буфере, затем Ваш Send() возвраты немедленно, в противном случае эти Send() блоки, пока нет некоторое место.

, Когда сокет находится в разъединенном состоянии, TCP/IP, стек предотвращает все дальнейшие операции с буфером, вот почему Send() возвраты ошибка.

Send() реализации основная проверка указателя, это означает, что она перестала работать, когда NULL указатель передается ей. Можно, вероятно, передать любую непустую константу как указатель, но Вы лучше выделяете 1 байт вместо того, чтобы составить постоянный — на всякий случай.

<час>

можно использовать любой метод, который Вы любите, поскольку ни один из них не потребление ресурса. Пока они используются для проверки сокетного соединения, они идентичны.

Что касается меня, я предпочел бы Receive(), поскольку это - то, что Вы обычно выполняете в цикле и ожидаете. Вы получаете ненулевое от [1 115], Вы обрабатываете данные; Вы получаете нуль, Вы обрабатываете разъединение.

22
ответ дан 27 November 2019 в 17:14
поделиться

Обычно можно было бы использовать Сокет. Выберите метод для определения состояния ряда сокетов (Сокет. Опрос для единственного сокета).

Оба из этих методов позволяют Вам запрашивать состояние сокета. Теперь, предположение, что Вы отследили это сокет, подключенный во-первых затем, Вы обычно звонили бы, Выбирают/Опрашивают на сокете прежде, чем делать попытку чтения. Если Выбирают/Опрашивают, указывают, что сокет читаем, это говорит Вам что:

  • Любой сокет имеет чтение вершины доступных данных, в этом случае Получают, возвратит доступные данные для чтения.
  • сокет сокета был закрыт, в этом случае когда Вы звоните, Получают 0 байтов, будет сразу возвращен (т.е. Если Выбирают/Опрашивают, указывают, что сокет читаем, и Вы звоните, Получают, но он сразу возвращается с 0 байтами затем, Вы знаете, что соединение было или Закрыто, Сброс или Завершенное.

Лично я никогда не использовал Опрос - я всегда использовал Выбор, но MSDN, кажется, предполагает, что Опрос является в значительной степени тем же как Выбором, но для единственных сокетов.

я также добавлю, что в большинстве случаев использование Выбора является самым эффективным и лучшим способом обработать Сокетные соединения.

1
ответ дан 27 November 2019 в 17:14
поделиться

"Если вам нужно определить текущее состояние соединения, выполните неблокирующий вызов Send с нулевым байтом. Если вызов завершается успешно или выдает код ошибки WAEWOULDBLOCK (10035), то сокет все еще подключен; в противном случае сокет больше не подключен». -- к сожалению, это даже не работает!

mySocket.Blocking = false;
byte[] buffer = new byte[1];
int iSent = mySocket.Send(buffer, 0, SocketFlags.None);
bConnected = mySocket.Connected;

bConnected всегда заканчивается как true, и вызов всегда возвращается успешно, даже если кабель Ethernet был отключен.

Кроме того, и, к сожалению, == отправка любых фактических данных также не обнаруживает разрыв соединения.

buffer[0] = 0xff ;
int iSent = mySocket.Send(buffer, 1, SocketFlags.None);

постоянно возвращает 1, как если бы действительно что-то отправил. В то время как рассматриваемое устройство даже больше не подключено.

4
ответ дан 27 November 2019 в 17:14
поделиться
Другие вопросы по тегам:

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