服务器+客户端解决方案

服务器采用一个比较成熟的网络引擎,之前做了N个游戏了..
客户端,好吧,之前有遇到问题,总之思路就是才要那个C#的SOCKET,也不要求多复杂,链接上,单独开一个发包线程,发包使用同步SEND.
收包...这个问题之前是:如果采用线程+同步RECV方法,各种平台(除了手机IOS5 6 7),完全没有问题...但是IPHONE上,同步RECV+线程方式,可能会有时成功有时失败,各种调,仍然不行,表现症状为,如果第一个包收到了,那么后面一切OK,如果第一个包客户端没收到,那么后面就收不到了...实在费解,但是同时发包一切正常.后来的解决方法是收包改用异步收,简简单单的异步收就是了,OK,这次正常了.
核心客户端代码我贴上来,大家看看有没有帮助,组包过程使用到了其他自定义类,大家看着自己处理了,就只贴核心收发链接过程,:

///开始连接-通过IP
 public static void StartConnectByIP(string _strIP, int _iPort)
    {///需要启动一个连接线程
        s_strIP = _strIP;
        s_iPort = _iPort;
        Thread ThreadOfConnectting = new Thread(new ThreadStart(T_Connectting));
        ThreadOfConnectting.Start();
        s_threadConnect = ThreadOfConnectting;
    }
 ///开始连接-通过域名
 public static void StartConnectByURL(string _strURL, int _iPort)
 {
  s_strURL = _strURL;
  s_iPort = _iPort;
  IPHostEntry _ipInfo = Dns.GetHostEntry(s_strURL);
  IPAddress _ip = _ipInfo.AddressList[0];
  s_strIP = _ip.ToString();
  Thread ThreadOfConnectting = new Thread(new ThreadStart(T_Connectting));
  ThreadOfConnectting.Start();
        s_threadConnect = ThreadOfConnectting;
 }
 ///发送内容
 public static bool SendSomething2Server(Byte[] _byte,int _iSizeCount)
 {
  bool _bFlag = false;
  if(s_pClientSocket != null && s_bStartedSenddingThread && s_threadSend != null)
  {
   lock (s_byTeBuffer)
   {
    CBaseDataPack _pPac = new CBaseDataPack(_iSizeCount, s_iSeqOfpack, _byte);
    if (_pPac != null)
    {
     if (_pPac.m_iTotalSize < c_iMaxCountBuffer - s_iNumShouldSend)
     {
      for (int _iCounter = 0; _iCounter < _pPac.m_iTotalSize; ++_iCounter)
      {
       s_byTeBuffer[_iCounter + s_iNumShouldSend] = _pPac.m_strBuffer[_iCounter];
      }
      s_iNumShouldSend += _pPac.m_iTotalSize;
      ++s_iSeqOfpack;
      _bFlag = true;
     }
    }
   }
  }
  return _bFlag;
 }
 /// 连接线程函数--当连接完成的时候线程会退出
 /// 实际上可以让其他对象来监视这个线程的运行
 /// 时间做超时处理
    public static bool s_bIfConnected = false; 
 public static void T_Connectting()
 {
  if (s_strIP != null && s_iPort > 0)
  {
   s_pClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
   if (s_pClientSocket != null)
   {
    IPEndPoint _ie = new IPEndPoint(IPAddress.Parse(s_strIP), s_iPort);//服务器的IP和端口
    if (_ie != null)
    {
     s_pClientSocket.Connect(_ie);
                    //PhoneScreenLog.AddLineInfo(s_pClientSocket.Available.ToString());
                    //Thread.Sleep(2000);
                    ///打开收包
                    ActiveRecvAbout();
                    ///打开发送线程
                    ActiveSendAbout();
                    s_bIfConnected = true;
                    PhoneScreenLog.AddLineInfo("CONNECT DOWN!");
                    DebugFunc.PrintDebugInfo("Connected!");
    }
   }
  }
 }
 /// 发送线程
 public static void T_Sendding()
 {
  while (true)
  {
        _label:
            if (!s_pClientSocket.Connected)
            {
                Thread.Sleep(1);
                goto _label;
            }
            if (!s_threadSend.IsAlive)
            {
                Thread.Sleep(1);
                s_threadSend.Start();
                goto _label;
            }
   lock (s_byTeBuffer)
   {
    if (s_iNumShouldSend > 0)
    {
     int _iNum = s_pClientSocket.Send(s_byTeBuffer, s_iNumShouldSend, SocketFlags.None);
     if (_iNum < s_iNumShouldSend)
     {
      for (int _iCounter = 0; _iCounter < s_iNumShouldSend - _iNum; ++_iCounter)
      {
       s_byTeBuffer[_iCounter] = s_byTeBuffer[_iCounter + _iNum];
      }
     }
     s_iNumShouldSend -= _iNum;
    }
   }
   Thread.Sleep(1);
  }
 }
    ///激活发送线程
    public static void ActiveSendAbout()
    {
        if (s_pClientSocket != null)
        {
            s_pClientSocket.SendTimeout = -1;
            s_pClientSocket.SendBufferSize = 1024 * 128;
            if (!s_bStartedSenddingThread)
            {
                s_threadSend = new Thread(new ThreadStart(T_Sendding));
                if (s_threadSend != null)
                {
                    s_threadSend.Priority = ThreadPriority.AboveNormal;
                    s_threadSend.Start();
                    s_bStartedSenddingThread = true;
                }
            }
        }
    }
 ///激活收包内容
 public static void ActiveRecvAbout()
 {
  if (s_pClientSocket != null)
  {
            s_pClientSocket.ReceiveTimeout = -1;
            s_pClientSocket.ReceiveBufferSize = 1024 * 128;
   if (!s_bStartedRecvedThread)
   {
                SetBeginRecv();
                s_bStartedRecvedThread = true;
                //s_threadRecv = new Thread(new ThreadStart(T_Recving));
                //if (s_threadRecv != null)
                //{
                //    s_threadRecv.Priority = ThreadPriority.AboveNormal;
                //    s_threadRecv.Start();
     
                //}
   }
  }
 }
 public static void SetBeginRecv()
    {
        s_pClientSocket.BeginReceive(s_byRecvBuffer, 0, c_iMaxCountBuffer, SocketFlags.None, new AsyncCallback(s_recvObj.RecvCallBack), null);
    } 
/// <summary>
/// 收包后的调用器
/// </summary>
public class CRecvMachine:object
{
    static object s_objLockOfRecv = new object();
    public void RecvCallBack(IAsyncResult ar)
    {
        int bytesRead = CClientBaseNet.s_pClientSocket.EndReceive(ar);
        PhoneScreenLog.AddLineInfo("RECEVE BASA PACKET!:");
        PhoneScreenLog.AddLineInfo(bytesRead.ToString());
        if(bytesRead > 0)
        {///对收到的包进行内容上的处理...因为这个函数可能是线程进入...所以
            lock (s_objLockOfRecv)
            {
                ClientNetDataWrapper.OnRecvedDataFromNetBass(CClientBaseNet.s_byRecvBuffer, bytesRead);
            }
        }
        CClientBaseNet.SetBeginRecv();
    }
}

 

posted on 2014-09-03 19:15  &大飞  阅读(261)  评论(0)    收藏  举报

导航