/// <summary> /// 设置远程主机信息 /// </summary> /// <param name="remoteIP">远程主机(广域网)</param> /// <param name="remoteLocalIP">远程主机(局域网)</param> public void setRemoteIP(IPEndPoint remoteLocalIP, IPEndPoint remoteIP) { #region 网络打洞互联 时间计数器 int TimeCount = 0; System.Timers.Timer timer1 = new System.Timers.Timer(); timer1.Interval = 500; timer1.Enabled = true; timer1.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e) { TimeCount++; if (toEP == null && TimeCount <= 20)//如果10秒后还未与对方建立联接 { UDPFramePacket packet = new UDPFramePacket(); packet.type = (byte)TransmitType.Penetrate;//打洞数据包 packet.Block = new byte[1400]; if (sockUDP != null && sockUDP.Listened) sockUDP.Send(remoteLocalIP, packet.ToBytes());//发送一次局域网正常打洞请求 UDPFramePacket packet1 = new UDPFramePacket(); packet1.type = (byte)TransmitType.Penetrate;//打洞数据包 packet1.Block = new byte[512]; if (sockUDP != null && sockUDP.Listened) sockUDP.Send(remoteLocalIP, packet1.ToBytes());//发送一次局域网小包打洞请求 UDPFramePacket packet2 = new UDPFramePacket(); packet2.type = (byte)TransmitType.Penetrate;//打洞数据包 packet2.Block = new byte[1400]; if (sockUDP != null && sockUDP.Listened) sockUDP.Send(remoteIP, packet2.ToBytes());//发送一次广域网打洞请求 UDPFramePacket packet3 = new UDPFramePacket(); packet3.type = (byte)TransmitType.Penetrate;//打洞数据包 packet3.Block = new byte[512]; if (sockUDP != null && sockUDP.Listened) sockUDP.Send(remoteIP, packet3.ToBytes());//发送一次广域网小包打洞请求 } else { //终止发送,并触发获得主机事件 timer1.Enabled = false; timer1.Dispose(); timer1 = null; if (toEP != null)//如果已与对方打洞成功并建立连接 { if (TimeCount <= 10) { connectedType = ConnectedType.UDPLocal;//标明是局域网连接 Console.WriteLine("局域网打洞成功,MTU=" + mtu.ToString() + ",打洞次数:" + TimeCount.ToString()); } else { connectedType = ConnectedType.UDPRemote;//标明是广域网连接 Console.WriteLine("广域网打洞成功,MTU=" + mtu.ToString() + ",打洞次数:" + TimeCount.ToString()); } } else//打洞超时,数据只能通过服务器中转 { Console.WriteLine("局域网打洞不成功,打洞次数::" + TimeCount.ToString()); mtu = 1400; toEP = remoteIP;//将对方的广域网远程主机信息记录下来 } OnTransmitConnected();//触发连接建立事件 } }; #endregion }
/// <summary> /// 发送数据包 /// </summary> /// <param name="type"></param> /// <param name="data"></param> public void sendData(TransmitType type, byte[] data) { if (data == null || data.Length == 0) return; SendTimestamp++; UDPFramePacket packet = new UDPFramePacket(); packet.type = (byte)type; packet.Timestamp = SendTimestamp; packet.Block = data; send(packet.ToBytes()); return; if (data.Length <= mtu) { packet.PacketCount = 1; packet.Block = data; send(packet.ToBytes()); Console.WriteLine(packet.type.ToString() + ":" + packet.ToBytes().Length.ToString()); } else { int count = data.Length / mtu; if (data.Length % mtu != 0) count += 1; int offSet = 0; byte[] block = new byte[mtu]; for (int i = 0; i < count; i++) { packet.PacketCount = count; packet.PacketIndex = i; if (offSet + mtu > data.Length) block = new byte[data.Length - offSet];//要发送的缓冲区 Buffer.BlockCopy(data, offSet, block, 0, block.Length); packet.Block = block; send(packet.ToBytes()); offSet += mtu; Console.WriteLine( packet.type.ToString() +":"+ packet.ToBytes().Length.ToString()); } } }