Основная проблема - время жизни объекта сокета. Вы создаете новый сокет как локальный в методе, но никогда не очищаете его. Это означает, что он останется там до тех пор, пока сборщик мусора не дойдет до его завершения, что может никогда не произойти.
Socket
является одноразовым, поэтому вы должны утилизировать его, когда закончите с ним , Это особенно важно для объектов, у которых есть побочные эффекты, связанные с их временем жизни - неразмещенный сокет слушателя все еще будет получать новые соединения и все еще занимать порт слушателя.
Socket AcceptClient(int port)
{
using (var listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp))
{
var endpoint = new IPEndPoint(IPAddress.Any, port);
listener.Bind(endpoint);
listener.Listen(1);
socket = listener.Accept();
// Explicit shutdown is a good idea for TCP sockets, though I'm not sure if it's needed for
// a listener socket.
listener.Shutdown(SocketShutdown.Both);
return socket;
}
}
Конечно, еще лучше Подход заключается в том, чтобы прекратить использование класса Socket
с очень низким уровнем и вместо этого использовать немного более высокий уровень TcpListener
. Это дает вам TcpClient
для принятого соединения и управляет временем жизни базового Socket
с помощью более дружественных методов, таких как Start
и Stop
. Сам по себе TcpClient
предоставляет интерфейс, более соответствующий принципу работы TCP, а не шаблон c общего приема / передачи простых сокетов. Если у вас нет особых потребностей, я настоятельно рекомендую использовать TcpListener
и TcpClient
.