/* * 判断当前连接是否建立 */ public bool IsConnected() { if (null == socket_) { return(false); } // 通过尝试获取服务器地址,判断连接是否断开 bool res = true; try { if (_remoteEndPoint == null) { res = false; } } catch (SystemException) { res = false; } // 连接意外断开后,调用用户回调函数 if (!res && connected_before_) { SuperDebug.Warning(DebugPrefix.Network, "connect to " + host_ + ":" + port_ + " break down."); connected_before_ = false; if (null != disconnect_callback_) { disconnect_callback_(); } } return(res); }
public bool SetData <T>(T data, PacketSession session) where T : IMessage { try { _content = data; _session = session; _cmdId = (ushort)session.CmdId; _bodyMem.Position = 0; _bodyMem.SetLength(0); _bodyMem.Write(NetUtils.UshortToBigEndian(_cmdId), 0, NetDefine.CMD_BYTES); _bodyMem.Seek(NetDefine.BODY_HEAD_LEN, SeekOrigin.Begin); session.WriteTo(_bodyMem); long sessionPos = _bodyMem.Position; data.WriteTo(_bodyMem); long contentPos = _bodyMem.Position; _bodyMem.Seek(NetDefine.CMD_BYTES, SeekOrigin.Begin); _bodyMem.Write(NetUtils.UshortToBigEndian((ushort)(sessionPos - NetDefine.BODY_HEAD_LEN)), 0, NetDefine.SESSION_LEN_BYTES); _bodyMem.Write(NetUtils.UintToBigEndian((uint)(contentPos - sessionPos)), 0, NetDefine.CONTENT_LEN_BYTES); //OutputBytes("true data:", body_.GetBuffer(), body_.Length); } catch (System.Exception e) { SuperDebug.Warning(DebugPrefix.Network, "Serialize " + typeof(T).ToString() + " meet exception " + e); return(false); } return(true); }
private void Reconnect() { _reconnectTimes += 1; _timer = 0; _status = Status.WaitingConnect; SuperDebug.Warning(DebugPrefix.Network, "===========Reconnect"); NetworkManager.Instance.LoginGameServer(); }
void ConsumePacket() { NetPacket packet = _client.Recv(0); if (packet != null) { DispatchPacket(packet); } else { /* 检查网络连接状态 */ if (CheckReachabilityChange()) { SuperDebug.Warning(DebugPrefix.Network, "=========== internetReachability changed to " + netReach); if (_client.IsConnected()) { SuperDebug.Warning(DebugPrefix.Network, "=========== disconnect by MonoClientPacketConsumer"); _client.Disconnect(); } } // disconnected check bool isConnected = _client.IsConnected(); if (!isConnected && _lastIsConnected && NetworkManager.Instance.onUnexpectedDisconnect != null) { NetworkManager.Instance.onUnexpectedDisconnect(); } _lastIsConnected = isConnected; if (!isConnected) { if (_status == Status.Normal) { _status = Status.WaitingConnect; Reconnect(); } else if (_status == Status.WaitingConnect) { _timer += Time.deltaTime; if (_timer > RECONNECT_INTERVAL) { ShowLoadingWheel(); Reconnect(); } } else if (_status == Status.RepeatLogin) { TryShowErrorDialog(); } } } return; }
public Type GetTypeByCmdID(ushort cmdID) { Type resType; if (!_cmdIDMap.TryGetValue(cmdID, out resType)) { SuperDebug.Warning(DebugPrefix.Network, "undefined cmdID=" + cmdID); } return(resType); }
public ushort GetCmdIDByType(Type type) { ushort resCmdID; if (!_typeMap.TryGetValue(type, out resCmdID)) { SuperDebug.Warning(DebugPrefix.Network, "undefined type=" + type); } return(resCmdID); }
/* * 设置心跳包 */ public bool SetKeepalive(int time_ms, NetPacket packet) { if (time_ms <= 0 || null == packet) { SuperDebug.Warning(DebugPrefix.Network, "time_ms<=0 or packet==null"); return(false); } keepalive_time_ms_ = time_ms; keepalive_packet_ = packet; return(true); }
/* * 启动接受数据的线程 */ private bool StartClientThread() { if (IsClientThreadRun()) { SuperDebug.Warning(DebugPrefix.Network, "recv thread is already running now, can not restart."); return(false); } client_producer_thread_ = new Thread(ClientProducerThreadHandler); client_producer_thread_.Start(); return(true); }
/* * 循环读取数据的线程, 逐个处理包 * 目前读取在主线程中,而不在网络线程中 */ private void ClientConsumerThreadHandler() { SuperDebug.Log(DebugPrefix.Network, "clientConsumer thread start."); while (IsConnected() || 0 < recv_queue_.Count) { // 等待的毫秒数,为 Timeout.Infinite,表示无限期等待。 NetPacket packet = Recv(Timeout.Infinite); if (packet != null) { SuperDebug.Log(DebugPrefix.Network, "clientConsumer recv: CmdId=" + packet.GetCmdId()); doCmd_callback_(packet); } else { SuperDebug.Warning(DebugPrefix.Network, "packet = null in clientConsumerThreadHandler"); } } SuperDebug.Log(DebugPrefix.Network, "clientConsumer thread stop."); }
/* * 同步方式发送一个标准消息包到服务器 */ public bool Send(NetPacket packet) { if (!IsConnected()) { SuperDebug.Warning(DebugPrefix.Network, "client is not connected, can not send now."); return(false); } // 序列化 MemoryStream ms = new MemoryStream(); packet.Serialize(ref ms); // 发送 /* fix: ObjectDisposedException: The object was used after being disposed. */ // 因为另一个线程会close掉socket,在close的同时send,就会导致上面的报错,加了Try-Catch */ try { SocketError error = new SocketError(); int send_len = socket_.Send(ms.GetBuffer(), 0, (int)ms.Length, SocketFlags.None, out error); if (error != SocketError.Success) { SuperDebug.Warning(DebugPrefix.Network, "send failed: " + error); return(false); } if (send_len != ms.Length) { //???does this happen? SuperDebug.Warning(DebugPrefix.Network, "packet_len=" + ms.Length + ", but only send " + send_len); return(false); } } catch (Exception e) { SuperDebug.Warning(DebugPrefix.Network, "exception e=" + e.ToString()); return(false); } return(true); }
/* * 建立连接 */ public bool Connect(string host, ushort port, int timeout_ms = 2000) //以毫秒为单位 { try { // 检查是否已经建立连接 if (IsConnected()) { SuperDebug.Warning(DebugPrefix.Network, "client is already connected to " + host_ + ":" + port_ + ", can not connect to other server now."); return(false); } // 赋值 host_ = host; port_ = port; timeout_ms_ = timeout_ms; // 根据host获取ip列表 IPAddress[] ip_list = Dns.GetHostAddresses(host_); if (0 == ip_list.Length) { SuperDebug.Warning(DebugPrefix.Network, "can not get any ip address from host " + host_); return(false); } // 尝试连接每个ip socket_ = null; _remoteEndPoint = null; for (int idx = 0; idx < ip_list.Length; idx++) { IPAddress ip_tmp = GetIPAddress(ip_list[idx]); SuperDebug.Log(DebugPrefix.Network, "try to connect to " + ip_tmp); IPEndPoint ipe = new IPEndPoint(ip_tmp, port_); Socket socket_tmp = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // 初始化socket属性 socket_tmp.NoDelay = true; socket_tmp.Blocking = true; socket_tmp.SendTimeout = timeout_ms_; socket_tmp.ReceiveTimeout = timeout_ms_; socket_tmp.ReceiveBufferSize = ClientDefine.g_recv_buf_size * 2; // 连接 timeout_event_.Reset(); socket_tmp.BeginConnect(ip_tmp, port_, new AsyncCallback(ConnectCallback), socket_tmp); // 超时等待连接建立 timeout_event_.WaitOne(timeout_ms, false); // 检验连接是否成功 if (socket_tmp.Connected) { socket_ = socket_tmp; _remoteEndPoint = ipe; SuperDebug.Log(DebugPrefix.Network, "socket_.ReceiveBufferSize= " + socket_.ReceiveBufferSize); break; } else { SuperDebug.Log(DebugPrefix.Network, "connect to " + ip_tmp + " timeout."); continue; } } // 检查是否成功连接 if (null == socket_) { SuperDebug.Warning(DebugPrefix.Network, "connect to " + host_ + ":" + port_ + " failed."); return(false); } else { SuperDebug.Log(DebugPrefix.Network, "connect to " + host_ + ":" + port_ + " succ."); SuperDebug.Log(DebugPrefix.Network, "_remoteEndPoint= " + _remoteEndPoint); } // 启动工作线程 StartClientThread(); // connected_before_ = true; } catch (System.Exception e) { SuperDebug.Error(DebugPrefix.Network, "connect to " + host + ":" + port + " meet exception " + e.ToString()); return(false); } return(true); }
/* * 同步方式接受多个消息 * 如果当前有可读消息,则立刻返回,否则超时等待设置的时间 */ private List <NetPacket> RecvPacketList() { // 检查连接状态 if (!IsConnected()) { SuperDebug.Warning(DebugPrefix.Network, "client is not connected, can not recv now."); return(null); } // 开始接受数据 List <NetPacket> list = new List <NetPacket>(); try { // 接受到缓存 byte[] recv_buf = new byte[ClientDefine.g_recv_buf_size - left_buf_len_]; SocketError error = new SocketError(); int recv_len = socket_.Receive(recv_buf, 0, recv_buf.Length, SocketFlags.None, out error); // 接受超时立刻返回 if (error == SocketError.TimedOut || error == SocketError.WouldBlock || error == SocketError.IOPending) { return(list); } // 如果接受数据长度为0,则表示连接出现异常,需要立刻使用回调函数通知使用方 if (error != SocketError.Success || 0 == recv_len) { SuperDebug.Warning(DebugPrefix.Network, "recv failed with recv_len=" + recv_len + ", error=" + error); socket_.Close(); socket_ = null; return(list); } // 合并上次剩余、本次收到的数据 byte[] total_buf = new byte[ClientDefine.g_recv_buf_size]; Array.Copy(left_buf_, 0, total_buf, 0, left_buf_len_); Array.Copy(recv_buf, 0, total_buf, left_buf_len_, recv_len); int total_len = recv_len + left_buf_len_; left_buf_len_ = 0; // 开始处理 int used = 0; // 一次可能recv多个packet,循环反序列化每个packet,并加入list while (used < total_len) { //缓存之前的有效数据 if (_tempPacket == null) { _tempPacket = new NetPacket(); } PacketStatus packet_status = _tempPacket.Deserialize(ref total_buf, ref used, total_len); if (PacketStatus.PACKET_CORRECT != packet_status) { // 存储残缺的数据 if (PacketStatus.PACKET_NOT_COMPLETE == packet_status) { left_buf_len_ = total_len - used; Array.Copy(total_buf, used, left_buf_, 0, left_buf_len_); } else { SuperDebug.Warning(DebugPrefix.Network, "deserialize packet failed. " + packet_status); } break; } else { list.Add(_tempPacket); _tempPacket = null; } } } catch (SystemException e) { if (IsConnected()) { SuperDebug.Error(DebugPrefix.Network, "recv failed: " + e); } } return(list); }