参考代码如下:
1 using System; 2 using System.Net; 3 using System.Net.Sockets; 4 using System.Collections.Generic; 5 using UnityGMClient.Network.Utility; 6 7 namespace UnityGMClient.Network 8 { 9 public class TCPConnect 10 { 11 private Socket m_CliSocket = null; 12 public const int s_nReadBufferSize = 1024 * 64; 13 public const int s_nWriteBufferSize = 1024 * 64; 14 private IPEndPoint m_IpEndPoint = null; 15 private Queue<GameMsgBase> m_WriteMsgQueue = null; 16 private NetReadBuffer m_Readbuffer = null; 17 private NetWriteBuffer m_Writebuffer = null; 18 private bool m_bConnecting = false; 19 private bool m_bSending = false; 20 private AddressFamily addressFamily = AddressFamily.InterNetwork; 21 22 public bool IsConnected 23 { 24 get 25 { 26 if (m_CliSocket != null && m_CliSocket.Connected) 27 { 28 return true; 29 } 30 return false; 31 } 32 } 33 34 public void InitServerConnect() 35 { 36 m_WriteMsgQueue = new Queue<GameMsgBase>(); 37 m_Readbuffer = new NetReadBuffer(s_nReadBufferSize); 38 m_Writebuffer = new NetWriteBuffer(s_nWriteBufferSize); 39 m_Readbuffer.Clear(); 40 m_Writebuffer.Clear(); 41 } 42 43 void ReinitSocket() 44 { 45 try 46 { 47 m_CliSocket.Close(); 48 if (m_IpEndPoint != null) 49 { 50 //m_CliSocket = new Socket(m_IpEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); 51 m_CliSocket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); 52 } 53 else 54 { 55 CTrace.Singleton.error("Reinit socket failed. IPEndPoint is null"); 56 } 57 } 58 catch (Exception e) 59 { 60 CTrace.Singleton.error("Reinit socket failed. exception = {0}", e.Message); 61 } 62 } 63 64 void PostDisconnectMsg() 65 { 66 GameMsgBase msg = new GameMsg_Disconnect(); 67 CGameClient.Singleton.msgQueue.Enqueue(msg); 68 } 69 70 public void Disconnect() 71 { 72 if (m_CliSocket.Connected) 73 { 74 ReinitSocket(); 75 PostDisconnectMsg(); 76 } 77 } 78 79 public void Connect(string server, int port) 80 { 81 if (!m_bConnecting) 82 { 83 IPAddress servAD = null; 84 85 try 86 { 87 if (server.Contains(".com") || server.Contains(".net") || server.Contains(".cn")) 88 { 89 IPAddress[] IPs = Dns.GetHostAddresses(server); 90 if (IPs.Length > 0) 91 { 92 servAD = IPs[0]; 93 } 94 } 95 else 96 { 97 servAD = IPAddress.Parse(server); 98 } 99 } 100 catch (Exception e) 101 { 102 CTrace.Singleton.error("Parse connect address failed. address = {0}, port = {1}, exception = {3}", server, port, e.Message); 103 } 104 105 if (servAD != null) 106 { 107 m_IpEndPoint = new IPEndPoint(servAD, port); 108 if(servAD.AddressFamily == AddressFamily.InterNetworkV6) { 109 addressFamily = AddressFamily.InterNetworkV6; 110 } else { 111 addressFamily = AddressFamily.InterNetwork; 112 } 113 m_CliSocket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp); 114 ReConnect(); 115 } 116 } 117 } 118 119 public void ReConnect() 120 { 121 try 122 { 123 if (m_CliSocket.Connected) 124 { 125 ReinitSocket(); 126 } 127 128 if (m_IpEndPoint != null) 129 { 130 CTrace.Singleton.debug("Begin to Connect address = {0}, port = {1}", m_IpEndPoint.Address.ToString() , m_IpEndPoint.Port.ToString()); 131 132 m_bConnecting = true; 133 m_CliSocket.BeginConnect(m_IpEndPoint.Address, m_IpEndPoint.Port, new AsyncCallback(ConnectCallback), this); 134 } 135 else 136 { 137 CTrace.Singleton.error("Connect Error. IPEndPoint is null"); 138 } 139 } 140 catch (Exception e) 141 { 142 CTrace.Singleton.error("Connect address failed. exception = {0}", e.Message); 143 } 144 } 145 146 public void ConnectCallback(IAsyncResult ar) 147 { 148 if (ar.IsCompleted) 149 { 150 m_bConnecting = false; 151 152 try 153 { 154 m_CliSocket.EndConnect(ar); 155 } 156 catch (Exception e) 157 { 158 CTrace.Singleton.error("Connect callback failed. exception = {0}", e.Message); 159 ReinitSocket(); 160 } 161 162 GameMsgBase msg = new GameMsg_Connect(m_CliSocket.Connected); 163 CGameClient.Singleton.msgQueue.Enqueue(msg); 164 165 if (m_CliSocket.Connected) 166 { 167 CTrace.Singleton.debug("connect success"); 168 BeginRecv(); 169 } 170 else 171 { 172 CTrace.Singleton.debug("connect failed"); 173 } 174 } 175 } 176 177 public void BeginRecv() 178 { 179 try 180 { 181 m_CliSocket.BeginReceive(m_Readbuffer.getRealBuffer(), 182 m_Readbuffer.getMaxDataPostion(), m_Readbuffer.getCapability(), 0, new AsyncCallback(ReceiveCallback), this); 183 } 184 catch (Exception e) 185 { 186 CTrace.Singleton.error("BeginRecv failed. exception = {0}", e.Message); 187 } 188 } 189 190 private void ReceiveCallback(IAsyncResult ar) 191 { 192 try 193 { 194 NetReadBuffer buffer = m_Readbuffer; 195 int nReadDataLen = m_CliSocket.EndReceive(ar); 196 197 if (nReadDataLen == 0) 198 { 199 ReinitSocket(); 200 PostDisconnectMsg(); 201 } 202 else 203 { 204 buffer.setMaxDataPostion(buffer.getMaxDataPostion() + nReadDataLen); 205 CGameClient.Singleton.msgMap.HandleMsg(m_Readbuffer); 206 m_Readbuffer.Settle(); 207 BeginRecv(); 208 } 209 } 210 catch (Exception e) 211 { 212 CTrace.Singleton.error("ReceiveCallback failed. exception = {0}, stack trace = {1}", e.Message,e.StackTrace); 213 ReinitSocket(); 214 PostDisconnectMsg(); 215 } 216 } 217 218 public void SendMessage(GameMsgBase Msg) 219 { 220 m_WriteMsgQueue.Enqueue(Msg); 221 } 222 223 public void TrySendMsg() 224 { 225 if (!m_bSending) 226 { 227 try 228 { 229 while (m_WriteMsgQueue.Count > 0) 230 { 231 GameMsgBase gamemsg = m_WriteMsgQueue.Peek(); 232 if (!gamemsg.encodeMessage(m_Writebuffer)) 233 break; 234 m_WriteMsgQueue.Dequeue(); 235 CTrace.Singleton.debug("Send Message. Message Type = {0}, Messenge Id = {1}", gamemsg.Type, gamemsg.MsgId); 236 } 237 238 if (m_Writebuffer.getPostion() > 0) 239 { 240 m_bSending = true; 241 m_CliSocket.BeginSend(m_Writebuffer.getWriteBuffer(), 0, m_Writebuffer.getPostion(), 0, new AsyncCallback(SendCallback), this); 242 } 243 } 244 catch (Exception e) 245 { 246 CTrace.Singleton.error("TrySendMsg failed. exception = {0}", e.Message); 247 m_bSending = false; 248 } 249 } 250 } 251 252 void SendCallback(IAsyncResult ar) 253 { 254 try 255 { 256 m_Writebuffer.Clear(); 257 m_CliSocket.EndSend(ar); 258 } 259 catch (Exception e) 260 { 261 CTrace.Singleton.error("Send Callback failed. exception = {0}", e.Message); 262 } 263 m_bSending = false; 264 } 265 } 266 }