6 个解决方案
#1
不太好判断
#2
模仿三次握手的方式。
#3
那么通常是怎么做的?如果客户端经常断开,服务器的资源一直得不到释放怎么可以呢?
#4
mark
#5
客户端断开有两种情况,一种是通讯故障或者对方失去响应导致超时,一种是对方关闭了连接,主动断开。超时这种情况,是无法判断的。因为超时之前无法知道这个连接是否还可以继续使用。
我们希望判断的是对方主动关闭连接的情况。
private bool IsCanRead(Socket sock) {
try {
//检查socket的状态是否可读
if (sock.Connected && sock.Poll(0, SelectMode.SelectRead)) {
byte[] bytes = new byte[1];
//因为TCP/IP协议无法精确的判断网络是否可用
//试读一个字符,Peek参数指定读取的字符不会从缓冲区中移除
//假如可读则表示连接可用
if (sock.Receive(bytes, 0, 1, SocketFlags.Peek) != 0) {
return true;
}
//Close("Disconnected.");
else {
return false;
}
}
else {
return true;
}
}
catch (SocketException e) {
if(e.SocketErrorCode==SocketError.ConnectionReset){
return false;
}
throw e;
}
}
这段代码还存在一定问题,对方断开时,如果缓冲区还存有未读出的字节的话,会返回true。所以还要结合socket.Availiable来判断。只有在socket.Availiable=0时,执行这段代码,才能判断socket是否被对方断开。
我们希望判断的是对方主动关闭连接的情况。
private bool IsCanRead(Socket sock) {
try {
//检查socket的状态是否可读
if (sock.Connected && sock.Poll(0, SelectMode.SelectRead)) {
byte[] bytes = new byte[1];
//因为TCP/IP协议无法精确的判断网络是否可用
//试读一个字符,Peek参数指定读取的字符不会从缓冲区中移除
//假如可读则表示连接可用
if (sock.Receive(bytes, 0, 1, SocketFlags.Peek) != 0) {
return true;
}
//Close("Disconnected.");
else {
return false;
}
}
else {
return true;
}
}
catch (SocketException e) {
if(e.SocketErrorCode==SocketError.ConnectionReset){
return false;
}
throw e;
}
}
这段代码还存在一定问题,对方断开时,如果缓冲区还存有未读出的字节的话,会返回true。所以还要结合socket.Availiable来判断。只有在socket.Availiable=0时,执行这段代码,才能判断socket是否被对方断开。
#6
楼主的设计有问题,如果是Threaded模式的服务器,应当用线程池来代替,关于线程池的描述参考一下msdn, 不过出于对性能的考虑,还是建议你使用IO异步的模式。
#1
不太好判断
#2
模仿三次握手的方式。
#3
那么通常是怎么做的?如果客户端经常断开,服务器的资源一直得不到释放怎么可以呢?
#4
mark
#5
客户端断开有两种情况,一种是通讯故障或者对方失去响应导致超时,一种是对方关闭了连接,主动断开。超时这种情况,是无法判断的。因为超时之前无法知道这个连接是否还可以继续使用。
我们希望判断的是对方主动关闭连接的情况。
private bool IsCanRead(Socket sock) {
try {
//检查socket的状态是否可读
if (sock.Connected && sock.Poll(0, SelectMode.SelectRead)) {
byte[] bytes = new byte[1];
//因为TCP/IP协议无法精确的判断网络是否可用
//试读一个字符,Peek参数指定读取的字符不会从缓冲区中移除
//假如可读则表示连接可用
if (sock.Receive(bytes, 0, 1, SocketFlags.Peek) != 0) {
return true;
}
//Close("Disconnected.");
else {
return false;
}
}
else {
return true;
}
}
catch (SocketException e) {
if(e.SocketErrorCode==SocketError.ConnectionReset){
return false;
}
throw e;
}
}
这段代码还存在一定问题,对方断开时,如果缓冲区还存有未读出的字节的话,会返回true。所以还要结合socket.Availiable来判断。只有在socket.Availiable=0时,执行这段代码,才能判断socket是否被对方断开。
我们希望判断的是对方主动关闭连接的情况。
private bool IsCanRead(Socket sock) {
try {
//检查socket的状态是否可读
if (sock.Connected && sock.Poll(0, SelectMode.SelectRead)) {
byte[] bytes = new byte[1];
//因为TCP/IP协议无法精确的判断网络是否可用
//试读一个字符,Peek参数指定读取的字符不会从缓冲区中移除
//假如可读则表示连接可用
if (sock.Receive(bytes, 0, 1, SocketFlags.Peek) != 0) {
return true;
}
//Close("Disconnected.");
else {
return false;
}
}
else {
return true;
}
}
catch (SocketException e) {
if(e.SocketErrorCode==SocketError.ConnectionReset){
return false;
}
throw e;
}
}
这段代码还存在一定问题,对方断开时,如果缓冲区还存有未读出的字节的话,会返回true。所以还要结合socket.Availiable来判断。只有在socket.Availiable=0时,执行这段代码,才能判断socket是否被对方断开。
#6
楼主的设计有问题,如果是Threaded模式的服务器,应当用线程池来代替,关于线程池的描述参考一下msdn, 不过出于对性能的考虑,还是建议你使用IO异步的模式。