日期:2014-05-20  浏览次数:20966 次

服务器端长连接,为什么客户端每次都要进行连接操作,服务端才能收到,内代码。
string strip = getIPAddress();
  // 把IP地址转换为IPAddress的实例
  IPAddress ipAd = IPAddress.Parse(strip);
  // 初始化监听器, 端口为10000
  _receiverSocket = new TcpListener(ipAd, 10000);
  // 开始监听服务器端口
  _receiverSocket.Start();

 while (true)
  {  
  Socket client = null;
  client = _receiverSocket.AcceptSocket();
  TSession session = new TSession(client);
  // 开始接受来自该客户端的数据
  session.ClientSocket.BeginReceive(session.ReceiveBuffer, 0,session.ReceiveBuffer.Length, SocketFlags.None, EndReceiveData, session);
  }

我现在的问题是,服务端接收客户端的连接,客户端每次都要进行连接,服务端才能收到。我的原意是:客户端跟服务端连接一次后不断开,客户端对服务端进行各种请求,进行长连接,但是我上面这样写了,每次到AcceptSocket时候,好像必须客户端每次进行Connect连接后,AcceptSocket才能不阻塞,进行下面的BeginReceive接收数据,比如:A电脑连接服务器B之后不断开,然后客户端过一会再进行别的请求,我这里如果客户端不再次连接,服务端收不到客户端的任何请求。简单点讲:我就是想客户端和服务端建立一次连接后,然后之后的直接向服务器请求就行,不用每次都进行连接。我这个服务端到底哪里需要改改?

TSession是自定义的

 public class TSession
  {
  public TSession(Socket client)
  {
  ClientSocket = client;
  }
  public Socket ClientSocket = null;  
  public byte[] ReceiveBuffer = new byte[2048];
  public DateTime LoginTime;
  }


 private static void EndReceiveData(IAsyncResult ar)
  {。。。。//数据处理
}

------解决方案--------------------
private static void EndReceiveData(IAsyncResult ar)
{
try
{
TSession readObject = (TSession)ar.AsyncState;
。。。。。
}
finally
{
session.ClientSocket.BeginReceive(session.ReceiveBuffer, 0, session.ReceiveBuffer.Length, 0,
new AsyncCallback(EndReceiveData), session);
}
}


Socket的回调很奇特,调用一次过后,需要再次注册调用,接收一次数据后,还要BeginReceive到处理函数。

------解决方案--------------------
长连接很麻烦,不仅仅是连上后不关就可以了,一般还会有定时发送心跳数据包来检查链路是否通信正常,如果发送的心跳数据包在指定的时间内没有收到回应那就认为链路断开了。这时候需要有重新恢复连接的机制。