【问题标题】:C# Socket SocketAsyncEventArgs reuse socket - ERRAddrAlreadyInUseC# Socket SocketAsyncEventArgs 重用套接字 - ERRAddrAlreadyInUse
【发布时间】:2017-06-05 07:31:58
【问题描述】:

我正在尝试为具有大量预分配的 Sockets 编写高性能库。我正在使用 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 进行 Connect/Disconnect 调用,因为这是一个套接字客户端,我认为使用 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}");
     }
}

【问题讨论】:

    标签: c# sockets


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-29
      • 2012-03-08
      • 2015-05-23
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      相关资源
      最近更新 更多