C#Socket SocketAsyncEventArgs重用套接字 - ERRAddrAlreadyInUse

时间:2017-06-04 22:27:21

标签: c# sockets

我正在尝试为Socket编写一个具有大量预分配功能的高性能库。我正在使用SocketAsyncEventArgs XXXAsync方法。当我在调用

后第二次尝试重新使用套接字时
  

_socket.DisconnectAsync(_socketAsyncEventArgs)

并设置

  

_socketAsyncEventArgs.DisconnectReuseSocket = true;

在进行断开连接呼叫之前,我在第二次连接呼叫时收到ERRAddrAlreadyInUse。我在创建Socket对象时尝试了以下选项,但没有任何变化。我知道我可以调用Close并创建新的Socket,但每次调用main函数时都会分配新对象,这很糟糕。

_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(false, 0));
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);

我也尝试将ReuseAddress设置为true,但没有任何改变 我正在等待第一次断开连接完成,然后我调用再次启动连接的方法。我也不是100%确定我是否应该使用不同的SocketAsyncEventArgs进行连接/断开调用,因为这是一个套接字客户端我看到使用1没有问题。

private void SocketConnect()
{
    try
    {
        if(!_init)
        {
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            {
                UseOnlyOverlappedIO = true,
                ReceiveBufferSize = _receiveBuffer.Length,
                SendBufferSize = _sendBuffer.Length,
            };
            _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(false, 0));
            _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);

            _socketAsyncEventArgs = new SocketAsyncEventArgs();
            _socketAsyncEventArgs.Completed += _socketProc;

            _init = !_init;
         }
         _socketAsyncEventArgs.RemoteEndPoint = _proxy != null ?
         new IPEndPoint(_proxy.IP, _proxy.Port) : new IPEndPoint(Dns.GetHostAddresses(DestinationUri.Host)[0].MapToIPv4(), DestinationUri.Scheme == "https" ? 443 : 80);
         var res = _socket.ConnectAsync(_socketAsyncEventArgs);
         if(!res)
             _socketProc(_socket, _socketAsyncEventArgs);
     }
     catch(SocketException socketException)
     {
         _completedTask.SetResult(false);
         Debug.WriteLine($"SocketConnect: {socketException.Message} : {socketException.ErrorCode} : {socketException.SocketErrorCode}");
     }
}

1 个答案:

答案 0 :(得分:0)

TIME_WAIT注册表中有一个TCP设置,标准设置为120。遗憾的是,只有C Winsock文档指定了这个,而不是C#one。我猜我必须强制关闭套接字并重新创建。