Правильный способ перестать слушать на сокете - PullRequest
19 голосов
/ 17 января 2009

У меня есть сервер, который прослушивает соединение через сокет:

public class Server
{
    private Socket _serverSocket;

    public Server()
    {
        _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _serverSocket.Bind(new IPEndPoint(IPAddress.Any, 1234));
        _serverSocket.Listen(1);
    }

    public void Start()
    {
        _serverSocket.BeginAccept(HandleAsyncConnectionMethod, null);
    }

    public void Stop()
    {
        //????? MAGIC ?????
    }

    //... rest of code here
}

Каков правильный (чистый) способ закрыть сокет?

Достаточно ли позвонить:

_serverSocket.Disconnect(true);

в методе Stop ()? или нужно выполнить другую работу, чтобы правильно закрыть соединение?

Ответы [ 7 ]

3 голосов
/ 17 января 2009

Завершение TCP-соединения правильно включает в себя четырехстороннее рукопожатие. Вы хотите, чтобы оба конца информировали друг друга о том, что они выключаются, а затем подтверждают отключение друг друга.

Википедия объясняет процесс: http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination

В этом посте объясняется, как это сделать в C #: http://vadmyst.blogspot.com/2008/04/proper-way-to-close-tcp-socket.html

2 голосов
/ 10 августа 2013

2 способа правильно закрыть его без исключений

1) создайте временный соединительный сокет и подключите его к прослушивающему сокету, чтобы его обработчик мог сработать, затем просто завершите его обычным EndAccept и после этого закройте оба.

2) просто закройте (0) прослушивающий сокет, что приведет к ложному выстрелу его обратного вызова, если вы затем посмотрите в свой прослушивающий сокет, вы увидите, что его состояние «закрыто» и «удалено». Вот почему вызов EndAccept вызовет исключение. Вы можете просто проигнорировать это и не вызывать EndAccept. Прослушивающая розетка немедленно отключится без тайм-аута.

2 голосов
/ 17 января 2009

Поскольку вы прослушиваете входящие TCP-соединения, вы можете использовать System.Net.Sockets.TcpListener , который имеет метод Stop (). Это не имеет асинхронных операций, хотя.

0 голосов
/ 19 декабря 2016

Самый чистый способ немедленного прерывания вызова Accept - это вызов _serverSocket.Dispose (); Любой другой вызов методов, таких как «Завершение работы» или «Отключение», вызовет исключение.

0 голосов
/ 17 января 2009

Во-первых, вы должны убедиться, что вы отслеживаете все клиентские сокеты, которые были созданы в процессе BeginAccept. Сначала отключите их с помощью методов Socket.Shutdown () и Socket.Close (). После того, как все они были закрыты, сделайте то же самое на самом прослушивающем сокете.

0 голосов
/ 17 января 2009

Вы должны использовать Socket.Shutdown () , а затем Socket.Close () . Socket.Disconnect () обычно используется только в том случае, если вы собираетесь повторно подключить один и тот же сокет.

0 голосов
/ 17 января 2009

То, что должно справиться с этим ... но если вам нужно быть абсолютно уверенным, вы всегда можете убить его огнем:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...