Socket.Получить блокировку даже после ShutDown () клиентом - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть серверное приложение с прослушиванием сокета:

server = new TcpListener(myEndPoint);

// etc.

socket = server.AcceptSocket();

while (true) {

    int size = socket.Receive(data); // application waits here for data.

    if (size == 0)
    {
        // handle disconnect
    }
    else
    {
        // process data.
    }
}

Теперь клиентское приложение подключается к этому ...

var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

socket.Connect(remoteIp, remotePort);

отправляет данные, а когда это делается, вызывает

socket.ShutDown(SocketShutdown.Both);

В этот момент я ожидаю, что сервер, который блокируется на socket.Receive(data), продолжит работу, но с size, равным 0.

согласно этой странице:

https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.receive?view=netframework-4.7.2

Если удаленный хост завершает соединение Socket методом Shutdown, и все доступные данные были получены, метод Receive завершится немедленно и вернет ноль байтов.

Но он просто ждет здесь вечно.

Самое смешное, если я подключаюсь к серверному приложению с помощью PuTTY, а затем закрываю PuTTY, то метод Receive() завершает и возвращает size = 0. Что PuTTY делает так Я нет?

Примечание. Я также пытался использовать TcpClient в клиентском приложении, но с этой же проблемой.

1 Ответ

0 голосов
/ 09 ноября 2018

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

Пробуя предложение Мину, я заметил, что если я просто закрыл сокет, не отправив данные, Receive() завершится правильно.

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

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