public bool ConnectCoroutine(string ip, ushort port, uint connectTimeout, uint recvTimeout, int buffSize, uint maxCmdCount, uint hearbeatID) { if (IsActive) { return(false); } Shutdown(); AddressFamily newaf = AddressFamily.InterNetwork; Socket socket = CreateSocket(newaf, buffSize); IPEndPoint endpoit = new IPEndPoint(IPAddress.Parse(ip), port); TCPConnectData cd = new TCPConnectData(); cd.endPoint = endpoit; cd.socket = socket; cd.connected = false; cd.connectTimeout = connectTimeout; cd.beginTime = GetTickCount(); Thread th = new Thread(new ParameterizedThreadStart(ThreadConnect)); th.Start(cd); m_ClientData = new TCPClientData(maxCmdCount); m_ClientData.Status = TCPStatusType.OK_CONNECTING; //正在连接 m_ClientData.Socket = socket; m_ClientData.BuffSize = buffSize; m_ClientData.RecvTimeout = recvTimeout; m_ClientData.HearbeatID = hearbeatID; m_ClientData.ConnectData = cd; return(true); }
void _ThreadRecv(object obj) { TCPClientData pclient = (TCPClientData)obj; uint recvTick = GetTickCount(); int offset = 0; int recvSize = 0; byte[] buff = new byte[pclient.BuffSize]; Socket socket = pclient.Socket; while (pclient.Status == TCPStatusType.OK_CONNECTED) { int curPos = offset + recvSize; int ret = 0; try { ret = socket.Receive(buff, curPos, buff.Length - curPos, SocketFlags.None); } catch { if (socket.Connected == false) { pclient.Status = TCPStatusType.ERR_DISCONNECT; Debug.Log("<连接断开3>" + DateTime.Now.ToString()); break; } } uint tick = GetTickCount(); if (ret > 0) { recvSize += ret; if (!RecvData(ref recvSize, ref offset, buff, pclient)) { if (pclient.Status == TCPStatusType.OK_CONNECTED) { pclient.Status = TCPStatusType.ERR_DISCONNECT; Debug.Log("<接收错误1>"); } break; } recvTick = tick; } else if (tick - recvTick > pclient.RecvTimeout) { pclient.Status = TCPStatusType.ERR_TIMEOUT; Debug.Log("<网络接收超时2>"); break; } Thread.Sleep(5); } Debug.Log("断开:" + pclient.Status); CloseSocket(socket); }
void _ThreadSend(object obj) { TCPClientData pdata = (TCPClientData)obj; uint halfTimeout = pdata.RecvTimeout >> 1; byte[] hearbeat = BitConverter.GetBytes(pdata.HearbeatID); Socket socket = pdata.Socket; uint sendTick = GetTickCount(); uint sendErrorCount = 0; while (pdata.Status == TCPStatusType.OK_CONNECTED) { uint tick = GetTickCount(); if (pdata.SendList.HasItem()) { byte[] cmd = pdata.SendList.GetItemNoRemove(); int ret = socket.Send(cmd, cmd.Length, SocketFlags.None); if (ret == cmd.Length) { pdata.SendList.GetItem(); sendTick = tick; sendErrorCount = 0; } else { if (++sendErrorCount >= 10) { pdata.Status = TCPStatusType.ERR_SEND_ERR; Debug.Log("<发送错误3>"); break; } } } else if (tick - sendTick > halfTimeout) { int ret = socket.Send(hearbeat, 4, SocketFlags.None); if (ret == 4) { sendTick = tick; } //Debug.LogError("这是一个心跳包" + DateTime.Now.ToString()); } Thread.Sleep(5); } }
public bool Connect(string ip, ushort port, uint connectTimeout, uint recvTimeout, int buffSize, uint maxCmdCount, uint hearbeatID) { if (IsActive) { return(false); } Shutdown(); AddressFamily newaf = AddressFamily.InterNetwork; Socket socket = CreateSocket(newaf, buffSize); IPEndPoint endpoit = new IPEndPoint(IPAddress.Parse(ip), port); TCPConnectData cd = new TCPConnectData(); cd.endPoint = endpoit; cd.socket = socket; cd.connected = false; cd.connectTimeout = connectTimeout; Thread th = new Thread(new ParameterizedThreadStart(ThreadConnect)); th.Start(cd); uint tick = GetTickCount(); while (GetTickCount() - tick < connectTimeout && cd.connected == false) { Thread.Sleep(50); } if (socket.Connected == false) { Debug.Log("Connect Timeout:" + (GetTickCount() - tick) + ", Set:" + connectTimeout); socket.Close(); return(false); } m_ClientData = new TCPClientData(maxCmdCount); m_ClientData.Status = TCPStatusType.OK_CONNECTED; m_ClientData.Socket = socket; m_ClientData.BuffSize = buffSize; m_ClientData.RecvTimeout = recvTimeout; m_ClientData.HearbeatID = hearbeatID; socket.Blocking = false; th = new Thread(new ParameterizedThreadStart(_ThreadRecv)); th.Start(m_ClientData); th = new Thread(new ParameterizedThreadStart(_ThreadSend)); th.Start(m_ClientData); Debug.Log("TCP Connected2."); return(true); }
bool RecvData(ref int recvSize, ref int offset, byte[] buff, TCPClientData pclient) { while (recvSize >= 4) { uint recvID = BitConverter.ToUInt32(buff, offset); if (recvID == pclient.HearbeatID) { offset += 4; recvSize -= 4; } else if (recvSize >= CMD_HEADER_SIZE) { int cmdSize = (int)recvID; if (cmdSize == 0) { pclient.Status = TCPStatusType.ERR_CMD_SIZE_ZERO; //命令长度为0 return(false); } if (cmdSize > pclient.BuffSize) { pclient.Status = TCPStatusType.ERR_CMD_SIZE_OVERFLOW; //命令长度大于buffsize; return(false); } if (recvSize >= cmdSize) { // Debug.Log("Inner Recv Cmd Count:" + pclient.RecvList.Count()); if (pclient.RecvList.HasSpace()) { TCPRecvData trd = ConvertRecvData(cmdSize, buff, offset); //byte[] cmd = new byte[cmdSize]; //Array.Copy(cmd, 0, buff, offset, cmdSize); pclient.RecvList.AddItem(trd); offset += cmdSize; recvSize -= cmdSize; } else { Debug.Log("接收队列已经满了:" + pclient.RecvList.Count() + ", " + DateTime.Now.ToLongTimeString()); pclient.Status = TCPStatusType.ERR_CMD_OVERFLOW;//命令队列已满 return(false); } } else { break; } } else { break; } } int freeBuffSize = pclient.BuffSize - (offset + recvSize); if (freeBuffSize < 128) { if (recvSize > 0) { System.Array.Copy(buff, offset, buff, 0, recvSize); } offset = 0; } return(true); }