IOCP怎么正确关闭socket

IOCP怎么正确关闭socket,第1张

如果服务端的Socket比客户端的Socket先关闭,会导致客户端出现TIME_WAIT状态,占用系统资源。

所以,必须等客户端先关闭Socket后,服务器端再关闭Socket才能避免TIME_WAIT状态的出现。

判断客户端Socket的关闭

最近试验发现,当客户端Socket关闭时,服务端的Socket会接收到0字节的通知。

private int Receive(StringBuilder sb)

{

int read = 0, total = 0

if (_Client != null)

{

try

{

byte[] bytes = new byte[SIZE]

int available = _Client.Available

do

{

read = _Client.Receive(bytes)//如果客户端Socket关闭,_Client会接受到read=0

total += read

if (read >0)

sb.Append(_Server.DefaultEncoding.GetString(bytes, 0, read))

} while (read >0 &&total <available)

}

catch (SocketException)

{

CloseSocket()

}

}

if (_Server.TraceInConsole &&total >0)

{

Console.WriteLine("Receive:" + total + "======================================")

Console.WriteLine(sb.ToString())

}

return total

}

利用0字节接收条件判断客户端Socket的关闭,开始执行服务端Socket关闭代码。

private void ThreadHandler()

{

if (_Server.TraceInConsole)

Console.WriteLine("Begin HttpRequest...")

try

{

while (true)

{

StringBuilder sb = new StringBuilder()

int receive = Receive(sb)

if (receive >0)

{

_Server.ReadRequest(this, sb.ToString())

_Server.Response(this)

_Server.ResponseFinished(this)

}

else

{

TryCloseSocket()

}

if (_Client == null)

break

}

}

catch (Exception ex)

{

if (_Server.TraceInConsole)

Console.WriteLine(ex.Message)

}

if (_Server.TraceInConsole)

Console.WriteLine(" www.hbbz08.com End HttpRequest.")

}

服务端Socket的关闭

如果直接调用Socket的Close方法会关闭得太快,可能导致客户端TIME_WAIT现象;而Thead.Sleep延时再调用Socket的Close方法也不理想。应该采用尝试向客户端发送数据,然后利用异常来关闭Socket,方法如下。

private void TryCloseSocket()

{

try

{

while (true)

{

Thread.Sleep(1500)

Send(HttpServer.BYTES_CRLF)//发送自定义的字节,如果客户端关闭出现SocketException,然后关闭服务端Socket

if (_Client == null)

break

}

}

catch (SocketException)

{

CloseSocket()

}

}

private void CloseSocket()

{

if (_Client != null)

{

_Client.Shutdown(SocketShutdown.Both)

_Client.Close()

_Client = null

if (_Server.TraceInConsole)

{

Console.WriteLine("Close socket.")

}

}

}

使用WSAGetOverlappedResult()函数,看一下具体的错误代码是什么!

在GetQueuedCompletionStatus返回错误,用WSAGetLastError()得到的并不是真正的错误代码!

估计是资源申请或释放方面的问题,如,资源不够!

你每个连接上投递了多少个异步发送接收请求?


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/324399.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-02
下一篇2023-05-02

发表评论

登录后才能评论

评论列表(0条)

    保存