| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2262 人关注过本帖
标题:[求助]异步通讯之关闭后重新自动连接
取消只看楼主 加入收藏
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
 问题点数:0 回复次数:10 
[求助]异步通讯之关闭后重新自动连接

我做了一个异步通讯的program,基本功能都实现了,现在的问题是Server和Client的非正常关闭连接以及正常关闭后的连接如何处理。
1。正常关闭

使用Client端的EndClient函数 ,Server端没有反应。后来我在BeginReceive的回调函数OnReceiveData中 加入这样的代码
public void OnReceiveData(IAsyncResult ar)
{
ReceiveDone.Set();
Sock = (Socket)ar.AsyncState;
try
{
int nBytesRec = Sock.EndReceive(ar); //收到数据长度
ReceiveDone.Set();
if (nBytesRec > 0)
{

string ss = Encoding.ASCII.GetString(Receive_Buffer, 0, nBytesRec);
。。。
}
else
{
listBox_Receive_Status.Items.Add("收到数据长度为零,远程客户机可能已经关闭,请重新监听。");
//这里我强行加入提示语句,因为发现无论是用EndClient的时候,Server端会进入BeginReceive的回调中。
问题1:Client端关闭,为什么会进入 BeginReceive的回调中
而且,收到数据长度为零。
问题2:在客户端关闭以后,作为接受的Socket Sock。connected属性=true。上面用蓝色字体显示

}


在这种情况下,我如何判断Client端已经关闭,进而对Server端也进行一些相应的处理啊?
比如 Server关掉,重启?




感谢各位的帮忙啊 ,多多关注啊。


搜索更多相关主题的帖子: 异步 通讯 Client 自动 Set 
2006-10-19 09:26
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
得分:0 
public void OnReceiveData(IAsyncResult ar)
{
ReceiveDone.Set();
Sock = (Socket)ar.AsyncState;
try
{
int nBytesRec = Sock.EndReceive(ar);
ReceiveDone.Set();
if (nBytesRec > 0)
{
string ss = Encoding.ASCII.GetString(Receive_Buffer, 0, nBytesRec);
listBox_Receive.Items.Add("接收:" + ss);
//FCS3000 f = new FCS3000("SeparateData");
//SeparateData(ss);
//AddintoMyfile(ss);
//listBox_Receive.Items.Add("接受:"+ss);
//收到要求发送data的报文GET
//发送有效数据。
//SendBackData(ss);
try
{
Sock.BeginReceive(Receive_Buffer, 0, Receive_Buffer.Length,
SocketFlags.None,
new AsyncCallback(OnReceiveData),
Sock);
ReceiveDone.WaitOne();
}
catch (ObjectDisposedException ode)
{
listBox_Send_Status.Items.Add("ObjectDisposedException" + ode.ToString());
}
catch (SocketException se)
{
listBox_Send_Status.Items.Add("发送出错,尚未建立远程连接:");
listBox_Send_Status.Items.Add("SocketException" + se.ToString());
listBox_Send_Status.Items.Add("远程主机关闭了连接,无法访问套接字,请重新连接。");
}
}
else
{
listBox_Receive_Status.Items.Add("收到数据长度为零,远程客户机可能已经关闭,请重新监听。");
}
}

catch (ObjectDisposedException ode)
{
listBox_Send_Status.Items.Add("ObjectDisposedException" + ode.ToString());
}
catch (SocketException se)
{
listBox_Send_Status.Items.Add("发送出错,尚未建立远程连接:");
listBox_Send_Status.Items.Add("SocketException:" + se.ToString());
listBox_Send_Status.Items.Add("远程客户机意外关闭了连接,无法访问套接字,请重新监听。");
}
}

这个是Server里面的BeginReceive的回调函数OnReceiveData


2006-10-19 10:23
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
得分:0 
主要的问题是,如果关闭了Client,Server这边如何及时地收到反映?是标志位?Sokcet的某种属性?还是什么?

同样的,如果Server关闭,Client这边如何及时地收到反映?是标志位?Sokcet的某种属性?还是什么?

因为我希望S 或者 C 主动关闭或者意外关闭以后,我能及时地得到通知,然后重新启动关闭的S或者C,重新迅速的建立连接,保证数据的发送。

2006-10-19 10:29
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
得分:0 
可不可以说详细一点,引发哪一类异常来关闭连接?

if (nBytesRec > 0)
{
string ss = Encoding.ASCII.GetString(Receive_Buffer, 0, nBytesRec);
listBox_Receive.Items.Add("接收:" + ss);
................
....................................................................
}
else
{
listBox_Receive_Status.Items.Add("收到数据长度为零,远程客户机可能已经关闭,请重新监听。");
}

比如我再CLient那边 调用 ENDClient 这个函数,则会进入Server的OnReceiveData,这样子收到数据为零。然后 进入Else{}
在里面提示信息,然后重新开始监听?


如果是直接关闭整个CLient端,则仍然会进入Server的OnReceiveData函数,

try
{
Sock.BeginReceive(Receive_Buffer, 0, Receive_Buffer.Length,
SocketFlags.None,
new AsyncCallback(OnReceiveData),
Sock);
ReceiveDone.WaitOne();
}

这部分code的 Sock.BeginReceive(Receive_Buffer, 0, Receive_Buffer.Length,
SocketFlags.None,
new AsyncCallback(OnReceiveData),
Sock);
这句话出错,抛出异常,我接该异常
catch (SocketException se)
{
listBox_Send_Status.Items.Add("发送出错,尚未建立远程连接:");
listBox_Send_Status.Items.Add("SocketException:" + se.ToString());
listBox_Send_Status.Items.Add("远程客户机意外关闭了连接,无法访问套接字,请重新监听。");
}

然后重新监听,等待CLient的连接。

可是如此的话是否太冗余,又没有直接一点的属性或者什么方法呢?当S或者C关闭以后就可以迅速通知对方。


2006-10-19 10:59
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
得分:0 
啊,除了我的处理之外,还有别的比较简单的或者其它方法吗?


2006-10-19 11:27
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
得分:0 
"为什么在回调里面有重新写一次啊" ??我没有贴监听的部分啊? 哪里啊? 哪一行贴一下吧。

2006-10-19 11:39
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
得分:0 
private void PreventErrorListen()
{
Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
LocalIP = new IPEndPoint(LocalIPAddress, int.Parse(textBox_Listen_Port.Text));
Listener.Bind(LocalIP);
listBox_Receive_Status.Items.Add("开始监听端口" + textBox_Listen_Port.Text + "...");
Listener.Listen(1);
MessageBox.Show("PreventErrorListen Listener.Connected="+Listener.Connected);
Listener.BeginAccept(new AsyncCallback(OnConnectRequest), Listener);
ListenDone.WaitOne();
}


public void OnConnectRequest(IAsyncResult ar)
{
listBox_Receive_Status.Items.Add("进入OnConnectRequest");

// Signal the main thread to continue.
ListenDone.Set();
MessageBox.Show("OnConnectRequest Listener.Connected=" + Listener.Connected);
Socket Listener1 = (Socket)ar.AsyncState; //此处的Listener是局部变量
MessageBox.Show("OnConnectRequest Listener1.Connected=" + Listener1.Connected);
try
{
ClientEndAccept = Listener1.EndAccept(ar);

listBox_Receive_Status.Items.Add("成功接受客户机" + ClientEndAccept.RemoteEndPoint + "的连接请求。。。");

//刚刚建立客户机与主机之间的连接
ClientEndAccept.BeginReceive(Receive_Buffer, 0, Receive_Buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveData), ClientEndAccept);
ReceiveDone.WaitOne();

Listener.BeginAccept(new AsyncCallback(OnConnectRequest), Listener);
ListenDone.WaitOne();

}
catch { }
}

这里是我的监听部分阿

2006-10-19 11:43
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
得分:0 
以下是引用chenjin145在2006-10-19 11:42:28的发言:

if (nBytesRec > 0)
{

string ss = Encoding.ASCII.GetString(Receive_Buffer, 0, nBytesRec);
。。。
}
else
{
shutdown
close
}

服務器 客戶端 都這樣關就行了


Server这边可以,当Client自己关闭的时候,它可以检测到。同时作出反映 。但是
Client这边的时候就不行了。
我这里说得Client现在只考虑它有一个socket进行连接及发送报文,并没有接收的部分啊。
假如Client只有一个socket进行连接及发送报文,那么Server关闭的时候Client怎么知道S关闭了啊 ?

有人说在C里面做一个timer或者死循环,隔一段时间就检测S是否仍然连接。。。
这样似乎也很麻烦啊


2006-10-19 11:56
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
得分:0 
以下是引用li_ming在2006-10-19 11:49:27的发言:
我也编过相关方面的程序,做的是短信网关,我是每隔固定时间给客户端发测试消息,查看客户端还是否存在

那么照你的说法,就是Server中有个函数,每隔固定时间给客户端发测试消息,查看客户端还是否存在
Client中有个函数,每隔固定时间给Server发测试消息,查看Server还是否存在。
这样子会不会比较麻烦 ?呵呵。。我还没有这样试过。


2006-10-19 11:58
jingzhao22visa
Rank: 1
等 级:新手上路
威 望:1
帖 子:343
专家分:0
注 册:2006-8-10
收藏
得分:0 
你這樣就只有
try
{
send
}
catch()
{
信息發不出去
}

目前我只能这样子。。。

还有别的方法吗?


2006-10-19 12:12
快速回复:[求助]异步通讯之关闭后重新自动连接
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.025872 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved