C# socket异步多客户端处理,双方采用长连接,服务器端如何维护多客户端

qiuqingpo 2010-09-28 09:27:18
C# socket异步多客户端处理,双方采用长连接.服务器端如何维护多客户端
当双方在信道上没有数据传输时每隔一段时间要发一次检测包.我在服务器端如何才能知道呢.
许多人说用一个hashtable.可我要保存的不只这些.不但有ip,socket.还有发送信息的客户端的编号
我怎么能才得到我的每个socket的最后一次有数据传输的时间?这也不是件容易的事
...全文
1204 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
xu_2007 2010-09-29
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 zanfeng 的回复:]
正在弄一个GIS的服务器。客户端是一些监测用的手持设备。
我用是tcp完成端口。心跳包大概也是一分钟一次。
数据量大一些,一天大概有几百万条数据。
楼主不防去codeproject上去看看。前些天有一个编辑推荐的完成端口的开源服务器程序。
[/Quote]

这位朋友可是用SocketAsyncEventArgs这个类实现完成端口?
xu_2007 2010-09-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 qiuqingpo 的回复:]
C# socket异步多客户端处理,双方采用长连接.服务器端如何维护多客户端
当双方在信道上没有数据传输时每隔一段时间要发一次检测包.我在服务器端如何才能知道呢.
许多人说用一个hashtable.可我要保存的不只这些.不但有ip,socket.还有发送信息的客户端的编号
我怎么能才得到我的每个socket的最后一次有数据传输的时间?这也不是件容易的事
[/Quote]

楼主朋友,我来一一回答你的问题:
1、当双方在信道上没有数据传输时每隔一段时间要发一次检测包.我在服务器端如何才能知道呢.许多人说用一个hashtable.可我要保存的不只这些.不但有ip,socket.还有发送信息的客户端的编号?

答:你服务端不一定要用hashtable来保存每个客户端会话类对象,注意我这里所说的客户端会话类对象是指一个这种类型的类:int soeckt client;//客户端套接字(里面包括了IP和端口等信息)
datetime firsttime;//上一次收到数据的时间
int msg; //客户端编号
好了,有了这个类后,你可以使用List<上面类的类型>这个泛型集合来保存每个连接到服务器端的SOCKET,也可以把hashtable的键值的类型定义为上面类的类型,这样就可以保存所有你所需要的信息了!


2、我怎么能才得到我的每个socket的最后一次有数据传输的时间?这也不是件容易的事?

答:在上面我们已经为类定义了一个:[color=#339966]“datetime firsttime“;//上一次收到数据的时间”变量成员,那么这个变量的意义就是记录上次收到数据包的时间,你可以通过把当前系统时间与这个变量相减所得出的值看作为两个数据包之间相隔了多少时间,以此作为超时判断的依据!具体作法可以在每个套接字接收到数据后就更新这个变量即可![/color]
qiuqingpo 2010-09-28
  • 打赏
  • 举报
回复

private void Receive(Socket client)
{

//构造容器state
StateObject state = new StateObject();
state.worksocket = client;
//从远程目标接收数据
try
{
client.BeginReceive(state.buffer, 0, StateObject.buffersize, 0, new AsyncCallback(ReceiveCallBack), state);
}
catch (Exception ex)
{
// Stop();
Console.WriteLine(ex.ToString());
}
// Thread.Sleep(1000);
}

是不是在这个里面呢?
我如何去做这个呢 当双方在信道上没有数据传输时每隔一段时间要发一次检测包.
能不能再具体一点!
大黄鸭在发光 2010-09-28
  • 打赏
  • 举报
回复
你用的异步就不用开线程了,拿到socket后你就循环接受就可以。
qiuqingpo 2010-09-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 wangyue4 的回复:]

每个客户端连进服务器只在第一次的时候需要服务端的监听程序。之后服务端就会获得客户端的socket。此后客户端再向服务端发消息完全就是通过这个socket。你可以在服务端获得socket后开线程循环接受命令。接受的命令包括心跳包、结束循环命令等等。
[/Quote]


/// <summary>
/// 异步接收
/// </summary>
/// <param name="ar"></param>
private void AcceptCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;

Socket handler = client.EndAccept(ar);
// Session newSession = new Session(client);
//event_Receive.Set();
Console.WriteLine("连接成功....");
Console.WriteLine(_Socket.LocalEndPoint.ToString());
Console.WriteLine(handler.RemoteEndPoint.ToString());
Receive(handler);
_Socket.BeginAccept(new AsyncCallback(AcceptCallback), _Socket);//等等下一个连接
// Thread.Sleep(1000);
}
catch
{
_Socket.Close();

}
}

我是异步接收的.那我是不是要把我的这个 Receive(handler);放在一个线程内了呢.这样每个连接都要一个线程.感觉有点浪费!
大黄鸭在发光 2010-09-28
  • 打赏
  • 举报
回复
每个客户端连进服务器只在第一次的时候需要服务端的监听程序。之后服务端就会获得客户端的socket。此后客户端再向服务端发消息完全就是通过这个socket。你可以在服务端获得socket后开线程循环接受命令。接受的命令包括心跳包、结束循环命令等等。
qiuqingpo 2010-09-28
  • 打赏
  • 举报
回复
高手们.救命呀.一个人也没有了!
fuheng 2010-09-28
  • 打赏
  • 举报
回复
标记一下,谢谢!我也要用这些
足球中国 2010-09-28
  • 打赏
  • 举报
回复
正在弄一个GIS的服务器。客户端是一些监测用的手持设备。
我用是tcp完成端口。心跳包大概也是一分钟一次。
数据量大一些,一天大概有几百万条数据。
楼主不防去codeproject上去看看。前些天有一个编辑推荐的完成端口的开源服务器程序。
CrazyCode1981 2010-09-28
  • 打赏
  • 举报
回复
其实你只要在百度找找 C#局域网通信 基本你要的代码都有 很容易看懂的
gs0038 2010-09-28
  • 打赏
  • 举报
回复
http://d.download.csdn.net/down/2548575/gs0038
通信下载例子
gs0038 2010-09-28
  • 打赏
  • 举报
回复
我也给你个思路吧
当服务器站收到客户站的信息为【内容信息】时,记录发送时间
当服务器收到客户站的信息为【检测包】这是客户站告诉服务器,说我已经多长时间没有收(发)信息了,或者是我已经多长时间没有与某客户联系了!时返回你通信息记录的时间给客户站,告诉他你最后发信息的时间!

记录时间的方式是,由于必须要区分这个时间是有哪个客户发送的,所以必须记录一个客户站ID,
xu_2007 2010-09-28
  • 打赏
  • 举报
回复
你给出的这个类是一个异步传送状态的类。我所说的是你自己自定义一个我给出的似类的类,然后每个套接字对应一个这个类,这样就形成了所谓的会员类!

private void AcceptCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
定义类.client=client;
定义类.msg=消息类型;
定义类.firsttime=当前系统时间;
list.item.add(定义类);

Socket handler = client.EndAccept(ar);
// Session newSession = new Session(client);
//event_Receive.Set();
Console.WriteLine("连接成功....");
Console.WriteLine(_Socket.LocalEndPoint.ToString());
Console.WriteLine(handler.RemoteEndPoint.ToString());
Receive(handler);
_Socket.BeginAccept(new AsyncCallback(AcceptCallback), _Socket);//等等下一个连接
// Thread.Sleep(1000);
}
catch
{
_Socket.Close();

}
}

注意看下我红色字添加的地方!
qiuqingpo 2010-09-28
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xu_2007 的回复:]

引用楼主 qiuqingpo 的回复:
C# socket异步多客户端处理,双方采用长连接.服务器端如何维护多客户端
当双方在信道上没有数据传输时每隔一段时间要发一次检测包.我在服务器端如何才能知道呢.
许多人说用一个hashtable.可我要保存的不只这些.不但有ip,socket.还有发送信息的客户端的编号
我怎么能才得到我的每个socket的最后一次有数据传输的时间?这也不是件容易……
[/Quote]
你所定义的这个是在StateObject这个类中定义吗?

public class StateObject
{
public Socket worksocket = null;
public const int buffersize = 1024;
public byte[] buffer = new byte[buffersize];
// public byte[] sendbuffer=new byte[buffersize];
public StringBuilder sb = new StringBuilder();
public StateObject()
{
}
}

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧