/// <summary> /// 向对方UDP端口发送握手数据 /// </summary> private void UdpHandshake() { try { IMLibrary.Class.msgAV msg = new IMLibrary.Class.msgAV(); if (!UdpHandshakeInfoClass)//如果为局域网握手 { msg.InfoClass = (byte)IMLibrary.Class.ProtocolAVTransmit.HandshakeLAN; this.sockUDP1.Send(this._OppositeUserInfo.LocalIP, this.OppositeUDPPort, msg.getBytes()); } else if (UdpHandshakeInfoClass)//如果为广域网握手 { msg.InfoClass = (byte)IMLibrary.Class.ProtocolAVTransmit.HandshakeWAN; this.sockUDP1.Send(this._OppositeUserInfo.IP, this.OppositeUDPPort, msg.getBytes()); } } catch { } }
private void TCPClient1_OnConnected(object sender, IMLibrary.Net.SockEventArgs e) { //IMLibrary.Calculate.WirteLog("已连接"); IMLibrary.Class.msgAV msg = new IMLibrary.Class.msgAV(); msg.InfoClass = (byte)IMLibrary.Class.ProtocolAVTransmit.GetAVTransmitProxyID; this.TCPClient1.SendData(msg.getBytes());//向服务器申请中转服务ID号 }
private void timerConnection_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (this.netClass != IMLibrary.Class.NetCommunicationClass.None)//如果UDP通信成功 { this.timerConnection.Enabled = false;//停止通信状态检测 if (this.AVConnected != null)//触发通信成功事件,并退出通信测试 this.AVConnected(this, this.netClass); return; } TimeOutCount++; if (TimeOutCount == 1 ) ///假设双方均在同一局域网内,则采用P2P UDP方式收发数据 { this.UdpHandshakeInfoClass = false;//UDP握手有两种可能,第一种为局域网,记为false,第二种为广域网,记为true;此时标记为局域网false if (!this.sockUDP1.Listened)//如果没有侦听,则侦听 this.UDPListen(); if (!this.IsGetLanUDP && this.AVGetUDPPort != null)//如果未与对方建立通信,触发UDP端口侦听成功事件,告之对方自己的UDP端口 { this.IsGetLanUDP = true; this.AVGetUDPPort(this, this.selfUDPPort, this.UdpHandshakeInfoClass); } } ///程序执行到这里表示双方假设为局域网通信不成立 ///2秒开始测试广域网UDP通信 if (TimeOutCount == 20 ) if (this._selfUserInfo.NetClass < (byte)IMLibrary.Class.NatClass.Tcp && this._OppositeUserInfo.NetClass < (byte)IMLibrary.Class.NatClass.Tcp) { //如果双方均在广域网上,采用UDP通信,且双方都不是 Symmetric NAT,则采用广域网UDP P2P通信 this.UdpHandshakeInfoClass = true;//UDP握手有两种可能,第一种为局域网,记为false,第二种为广域网,记为true;此时标记为广域网 if (!this.sockUDP1.Listened)//如果没有侦听,则侦听 this.UDPListen(); IMLibrary.Class.msgAV msg = new IMLibrary.Class.msgAV(); msg.InfoClass = (byte)IMLibrary.Class.ProtocolAVTransmit.GetUDPWANInfo;//通信协议,获得UDP套接字的广域网UDP端口 this.sockUDP1.Send(_serverIp, _serverUDPPort, msg.getBytes()); //Calculate.WirteLog("测试采用广域网方式通信"); } else { TimeOutCount = 40;//如果只能通过代理传输,则开始使用代理 } //4秒后开始测试广域网 if (TimeOutCount == 40) { //如果用户自己与对方其中一方使用TCP登录,则需要使用TCP代理服务器中转数据传输 this.TCPClient1.InitSocket(this._selfUserInfo.LocalIP, 0);//邦定本机TCP随机端口 this.TCPClient1.Connect(this._serverIp, _serverTCPPort);//TCP检测联接服务器 } ///程序执行到此表示不能建立任何传输联接,触发无法联接事件 //7秒后开始测试广域网 if (TimeOutCount > 70) { if (this.AVConnected != null)//触发通信成功事件,并退出通信测试 this.AVConnected(this, this.netClass); this.timerConnection.Enabled = false;//停止通信状态检测 this.CancelTransmit(true);//取消传输 return; } }
/// <summary> /// 设置对方传输UDP本地端口 /// </summary> /// <param name="Port">传输UDP本地端口</param> public void setGetUdpLocalPort(int Port, bool udpHandshakeInfoClass) { this.OppositeUDPPort = Port;//设置对方UDP端口号 this.UdpHandshakeInfoClass = udpHandshakeInfoClass;//握手方式 System.Threading.Thread.Sleep(100); if (!udpHandshakeInfoClass)//如果自己还未UDP侦听,采用局域网方式通信 { if (!this.sockUDP1.Listened)//如果没有侦听 this.UDPListen();//随机UDP侦听 if (!this.IsGetLanUDP && this.AVGetUDPPort != null)//如果未与对方建立通信,则产生获得端口事件 { this.IsGetLanUDP = true; this.AVGetUDPPort(this, this.selfUDPPort, false); } //Calculate.WirteLog( "对方要求采用局域网方式通信"); } else if (udpHandshakeInfoClass)//采用广域网方式通信 { if (!this.sockUDP1.Listened)//如果没有侦听 this.UDPListen();//随机UDP侦听 IMLibrary.Class.msgAV msg = new IMLibrary.Class.msgAV(); msg.InfoClass = (byte)IMLibrary.Class.ProtocolAVTransmit.GetUDPWANInfo;//通信协议 this.sockUDP1.Send(_serverIp, _serverUDPPort, msg.getBytes());//获得文件传输套接字的广域网UDP端口 //Calculate.WirteLog("对方要求采用广域网方式通信"); } if (!timersUdpPenetrate.Enabled)//如果未握手,则开始握手 timersUdpPenetrate.Enabled = true;//开始向对方UDP端口握手(打洞),如果成功,表示可以进行UDP通信 }