Обнаружение разъединения клиента TCP

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
67
задан Zxaos 28 July 2014 в 19:23
поделиться

6 ответов

выберите (с комплектом масок чтения), возвратится с сообщенным дескриптором, но когда Вы будете использовать ioctl* для проверки числа байтов, ожидающих, чтобы быть считанными, это будет нуль. Это - знак, что сокет был разъединен.

Это - большое обсуждение различных методов проверки, что клиент разъединился: Stephen Cleary, Обнаружение Полуоткрытых (Отброшенных) Соединений .

* для Windows используют ioctlsocket.

0
ответ дан 24 November 2019 в 14:40
поделиться

Подробно остановиться на этом немного больше:

, Если Вы выполняете сервер Вы или должны использовать TCP_KEEPALIVE, чтобы контролировать соединения клиента, или сделать что-то подобное сами или иметь знание о данных/протоколе, что Вы работаете на основе соединения.

В основном, если соединение уничтожается (т.е. не правильно закрытое) затем, сервер не заметит, пока это не попытается записать что-то клиенту, который является тем, чего проверка активности достигает для Вас. С другой стороны, если Вы знаете протокол лучше, Вы могли бы просто разъединиться на тайм-ауте неактивности так или иначе.

12
ответ дан 24 November 2019 в 14:40
поделиться

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

2
ответ дан 24 November 2019 в 14:40
поделиться
"""
tcp_disconnect.py
Echo network data test program in python. This easily translates to C & Java.

A server program might want to confirm that a tcp client is still connected 
before it sends a data. That is, detect if its connected without reading from socket.
This will demonstrate how to detect a TCP client disconnect without reading data.

The method to do this:
1) select on socket as poll (no wait)
2) if no recv data waiting, then client still connected
3) if recv data waiting, the read one char using PEEK flag 
4) if PEEK data len=0, then client has disconnected, otherwise its connected.
Note, the peek flag will read data without removing it from tcp queue.

To see it in action: 0) run this program on one computer 1) from another computer, 
connect via telnet port 12345, 2) type a line of data 3) wait to see it echo, 
4) type another line, 5) disconnect quickly, 6) watch the program will detect the 
disconnect and exit.

John Masinter, 17-Dec-2008
"""

import socket
import time
import select

HOST = ''       # all local interfaces
PORT = 12345    # port to listen

# listen for new TCP connections
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
# accept new conneciton
conn, addr = s.accept()
print 'Connected by', addr
# loop reading/echoing, until client disconnects
try:
    conn.send("Send me data, and I will echo it back after a short delay.\n")
    while 1:
        data = conn.recv(1024)                          # recv all data queued
        if not data: break                              # client disconnected
        time.sleep(3)                                   # simulate time consuming work
        # below will detect if client disconnects during sleep
        r, w, e = select.select([conn], [], [], 0)      # more data waiting?
        print "select: r=%s w=%s e=%s" % (r,w,e)        # debug output to command line
        if r:                                           # yes, data avail to read.
            t = conn.recv(1024, socket.MSG_PEEK)        # read without remove from queue
            print "peek: len=%d, data=%s" % (len(t),t)  # debug output
            if len(t)==0:                               # length of data peeked 0?
                print "Client disconnected."            # client disconnected
                break                                   # quit program
        conn.send("-->"+data)                           # echo only if still connected
finally:
    conn.close()
0
ответ дан 24 November 2019 в 14:40
поделиться

It's really easy to do: reliable and not messy:

 Try
 Clients.Client.Send(BufferByte)
 Catch verror As Exception
 BufferString = verror.ToString
 End Try
 If BufferString <> "" Then
 EventLog.Text &= "User disconnected: " + vbNewLine
 Clients.Close()
 End If
-3
ответ дан 24 November 2019 в 14:40
поделиться

Библиотека apr из проекта apache является хорошим справочником по этой проблеме. Он использует опрос со значением таймаута, чтобы проверить, разорвано ли соединение на другой стороне.

-2
ответ дан 24 November 2019 в 14:40
поделиться
Другие вопросы по тегам:

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