сервер - сокеты c#




Socket.Close действительно не закрывает сокет tcp?(C#) (3)

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

Попробуйте подключиться синхронно - или закрыть его в OnSocketConnected чтобы вы могли увидеть эффект закрытия действительно подключенного сокета.

Похоже, что использование socket.Close () для сокета tcp не полностью закрывает сокет. В следующем примере я пытаюсь подключиться к example.com в порту 9999, который не открывается, и после короткого таймаута я пытаюсь закрыть сокет.

  for (int i = 0; i < 200; i++)
  {
    Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    sock.LingerState = new LingerOption(false, 0);
    sock.BeginConnect("www.example.com", 9999, OnSocketConnected, sock);
    System.Threading.Thread.Sleep(50);
    sock.Close();
  }

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

  TCP    israel-xp:6506         www.example.com:9999   SYN_SENT
  TCP    israel-xp:6507         www.example.com:9999   SYN_SENT
  TCP    israel-xp:6508         www.example.com:9999   SYN_SENT
  TCP    israel-xp:6509         www.example.com:9999   SYN_SENT

ИЗМЕНИТЬ . Хорошо, какой-то контекст отсутствовал. Я использую beginconnect, потому что ожидаю, что соединение сокета завершится неудачно (9999 не открывается), и в моем реальном коде я вызываю socket.Close () как только установлен таймер. В OnSocketConnected я вызываю EndConnect, который генерирует исключение (пытается вызвать метод расположенного объекта). Моя цель - короткий тайм-аут для этапа подключения сокета.

Вы знаете, что я делаю неправильно? Благодаря!


Вы инициализируете новый Socket в каждом цикле ... с * .close () вы закрываете старое, и в начале вы создаете новый с теми же параметрами, что и Socket раньше.


По дизайну вы должны всегда вызывать Shutdown перед закрытием сокета.

mySocket.Shutdown(SocketShutdown.Both);
mySocket.Close();

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

У Джона Скита также есть точка, что, поскольку вы открываете соединение асинхронно, оно может фактически соединяться, когда вы пытаетесь его закрыть. Однако, если вы вызываете « Shutdown на нем, это не позволит получать информацию, как вы переживаете.

Изменить: вы можете только Shutdown сокет, который уже подключен, поэтому помните об этом, когда пишете свой код.







tcp