【发布时间】: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}");
}
}
【问题讨论】: