' / .
' / .- .
. .- .-
./ .--...
.-------- 0 .--
/ .......
' ..
'........ ----
. --..
. .---.. -
分 o . ' -.
分 / '
/ ' ' '
\-分--/....... . ' ' ' '
\ __/ - - -' ' ' '
' ' ' '
o ' ' ' '
' ' '
-..'.----------.
I ----------
/////////.
' / .- .
. .- .-
./ .--...
.-------- 0 .--
/ .......
' ..
'........ ----
. --..
. .---.. -
分 o . ' -.
分 / '
/ ' ' '
\-分--/....... . ' ' ' '
\ __/ - - -' ' ' '
' ' ' '
o ' ' ' '
' ' '
-..'.----------.
I ----------
/////////.
确定一个或多个套接字的状态
SocketException 访问 Socket 时发生操作系统错误。
public bool Poll(
int microSeconds,
SelectMode mode
);
microSeconds
等待响应的时间(以微秒为单位)。
mode
SelectMode 值之一。SelectRead true,如果 Listen 已被调用且连接正处于挂起状态,而 Accept 将会成功
-或-true,如果数据可供读取-或-true,如果连接已被关闭、重置或终止;否则,返回 false。
SelectWrite true,如果正在处理 Connect 并且连接已成功
-或-true,如果数据已被发送;否则,返回 false。
SelectError true,如果正在处理不阻塞的 Connect 并且连接已失败
-或-true,如果 OutOfBandInline 未被设置且带外数据可用;否则,返回 false。
出错在public void OnRecievedData( IAsyncResult ar )这个函数的int nBytesRec = sock.EndReceive( ar );
可以看到出错的原因是"远程主机已经强制关闭了连接",我在出错之前加上
if (sock.connected)
这个判断,加上之后,错误的语句往后面跳了两行,变成了Invoke( m_AddMessage, new string [] { sRecieved } );
这个语句,原因是"不能使用空值"
真的是莫名其妙,而且可以设置断点看到这个时候的SOCK.CONNECTED属性为FALSE,也就是说不能执行到这个地方才对的
public void OnRecievedData( IAsyncResult ar )
{
Socket sock = ar.AsyncState as Socket;
if( sock == null || !sock.Connected )
return;
try
{
....
}
catch()
{
if( !sock.Connected )
{ yourFunc();}
}
或着在异常捕捉中,进一步处理.
谢谢,这样我已经试过了,我上面说过了,判断里面的那个RETURN根本就不会执行,继续往下的时候到INVOKE语句里面又抛出....
创建一个项目,windows应用程序,放两个按钮,一个启动,一个停止:
启动里面:
IPEndPoint ipLocalEndPoint = new IPEndPoint(IPAddress.Parse("192.168.0.18"),1111);
ListenSoc = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp );
ListenSoc.Bind(ipLocalEndPoint);
ListenSoc.Listen(5);
ListenSoc.BeginAccept(new AsyncCallback(AcceptCallback),ListenSoc);
停止按钮里面:
try
{
ListenSoc.Shutdown(SocketShutdown.Both);
ListenSoc.Close();
if(ListenSoc.Connected) MessageBox.Show("无法关闭");
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
在家两个回掉函数:
public static void AcceptCallback(IAsyncResult ar)
{
try
{
//connectDone.Set();
byte[] bytes=new byte[1024];
Socket listener=(Socket)ar.AsyncState;
Socket handler=listener.EndAccept(ar);
handler.BeginAccept(new AsyncCallback(AcceptCallback),handler);
handler.BeginReceive(bytes,0,bytes.Length,0,new AsyncCallback(ReceiveCallback),handler);//handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,new AsyncCallback(ReadCallback),state);
//receiveDone.WaitOne();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
} }
public static void ReceiveCallback(IAsyncResult ar)
{
Socket aa=(Socket)ar.AsyncState;
int bb=aa.EndReceive(ar);
}
呵呵,至于怎么解决这个问题,自己程序想办法了。
TCP是有连接的,如果服务器程序正常退出,底层tcp 会通知 client, 在 client 端会产生异常。用上面这段程序就行了如果服务器突然死机,或掉电, client 就无法从底层 tcp 及时得到消息,我的做法是 client 隔一段时间连接一次 server, 比如1秒,网络负担也不大。
你不需要先知道是否连接再收发数据,你只需要直接收发数据,加上异常处理即可。
有的话, 能不能发一份代码给我,十分的感谢!!
[email protected]