/// <summary> /// 发送文件包 /// </summary> /// <param name="fileMsg"></param> private void sendFilePak(UDPPacket fileMsg) { if (toEP != null) { if (TFileInfo.connectedType == ConnectedType.None || TFileInfo.connectedType == ConnectedType.UDPServer)//如果通过服务器中转 { fileMsg.RemoteIP = toEP.Address;//告诉服务器接收方的IP和端口 fileMsg.Port = toEP.Port; sockUDP.Send(ServerEP, fileMsg.ToBytes()); } else//如果直连,直接发送数据给对方 { sockUDP.Send(toEP, fileMsg.ToBytes()); } } }
/// <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秒后还未与对方建立联接 { UDPPacket ftMsg = new UDPPacket(); ftMsg.type = (byte)TransmitType.Penetrate;//打洞数据包 ftMsg.Block = new byte[1400]; sockUDP.Send(remoteLocalIP, ftMsg.ToBytes());//发送一次局域网正常打洞请求 UDPPacket ftMsg1 = new UDPPacket(); ftMsg1.type = (byte)TransmitType.Penetrate;//打洞数据包 ftMsg1.Block = new byte[512]; sockUDP.Send(remoteLocalIP, ftMsg1.ToBytes());//发送一次局域网小包打洞请求 UDPPacket ftMsg2 = new UDPPacket(); ftMsg2.type = (byte)TransmitType.Penetrate;//打洞数据包 ftMsg2.Block = new byte[1400]; sockUDP.Send(remoteIP, ftMsg2.ToBytes());//发送一次广域网打洞请求 UDPPacket ftMsg3 = new UDPPacket(); ftMsg3.type = (byte)TransmitType.Penetrate;//打洞数据包 ftMsg3.Block = new byte[512]; sockUDP.Send(remoteIP, ftMsg3.ToBytes());//发送一次广域网小包打洞请求 } else { //终止发送,并触发获得主机事件 timer1.Enabled = false; timer1.Dispose(); timer1 = null; if (toEP != null)//如果已与对方打洞成功并建立连接 { if (TimeCount <= 10) { TFileInfo.connectedType = ConnectedType.UDPLocal;//标明是局域网连接 Console.WriteLine("局域网打洞成功,MTU=" + mtu.ToString() + ",打洞次数:" + TimeCount.ToString()); } else { TFileInfo.connectedType = ConnectedType.UDPRemote;//标明是广域网连接 Console.WriteLine("广域网打洞成功,MTU=" + mtu.ToString() + ",打洞次数:" + TimeCount.ToString()); } } else//打洞超时,数据只能通过服务器中转 { Console.WriteLine("局域网打洞不成功,打洞次数::" + TimeCount.ToString()); mtu = 1400; toEP = remoteIP;//将对方的广域网远程主机信息记录下来 } if (!IsSend)//如果是文件接收端 RequestSendFilePak();//开始获取文件数据包 OnFileTransmitConnected();//触发连接建立事件 } }; #endregion }