Подтвердить что ты не робот

Правильный способ прекратить прослушивание сокета

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

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()? или есть ли другая работа, которая должна произойти, чтобы закрыть соединение чисто?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

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