/// <summary>
 /// 向对方UDP端口发送握手数据
 /// </summary>
 private void UdpHandshake()
 {
     try
     {
         CSS.IM.Library.Class.msgAV msg = new CSS.IM.Library.Class.msgAV();
         if (!UdpHandshakeInfoClass)//如果为局域网握手
         {
             msg.InfoClass = (byte)CSS.IM.Library.Class.ProtocolAVTransmit.HandshakeLAN;
             this.sockUDP1.Send(this._OppositeUserInfo.LocalIP, this.OppositeUDPPort, msg.getBytes());
         }
         else if (UdpHandshakeInfoClass)//如果为广域网握手
         {
             msg.InfoClass = (byte)CSS.IM.Library.Class.ProtocolAVTransmit.HandshakeWAN;
             this.sockUDP1.Send(this._OppositeUserInfo.IP, this.OppositeUDPPort, msg.getBytes());
         }
     }
     catch { }
 }
 private void RemoteAssist_Socket_DataArrival(object sender, SockEventArgs e)
 {
     CSS.IM.Library.Class.msgAV msg = new CSS.IM.Library.Class.msgAV(e.Data);
     this.DataArrival(msg, CSS.IM.Library.Class.NatClass.FullCone, e.IP, e.Port);
 }
 private void TCPClient1_OnDataArrival(object sender, CSS.IM.Library.Net.SockEventArgs e)
 {
     //if (e.Data.Length < 10) return;
     CSS.IM.Library.Class.msgAV msg = new CSS.IM.Library.Class.msgAV(e.Data);
     this.DataArrival(msg, CSS.IM.Library.Class.NatClass.Tcp, null, 0);
 }
        private void timerConnection_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (this.netClass != CSS.IM.Library.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)CSS.IM.Library.Class.NatClass.Tcp && this._OppositeUserInfo.NetClass < (byte)CSS.IM.Library.Class.NatClass.Tcp)
                {
                    //如果双方均在广域网上,采用UDP通信,且双方都不是 Symmetric NAT,则采用广域网UDP P2P通信
                    this.UdpHandshakeInfoClass = true;//UDP握手有两种可能,第一种为局域网,记为false,第二种为广域网,记为true;此时标记为广域网
                    if (!this.sockUDP1.Listened)//如果没有侦听,则侦听
                        this.UDPListen();

                    CSS.IM.Library.Class.msgAV msg = new CSS.IM.Library.Class.msgAV();
                    msg.InfoClass = (byte)CSS.IM.Library.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;
            }
        }
 private void TCPClient1_OnConnected(object sender, CSS.IM.Library.Net.SockEventArgs e)
 {
     //CSS.IM.Library.Calculate.WirteLog("已连接");
     CSS.IM.Library.Class.msgAV msg = new CSS.IM.Library.Class.msgAV();
     msg.InfoClass = (byte)CSS.IM.Library.Class.ProtocolAVTransmit.GetAVTransmitProxyID;
     this.TCPClient1.SendData(msg.getBytes());//向服务器申请中转服务ID号
 }
 private void sockUDP1_DataArrival(object sender, CSS.IM.Library.Net.SockEventArgs e)
 {
     //if (e.Data.Length < 10) return;
     CSS.IM.Library.Class.msgAV msg = new CSS.IM.Library.Class.msgAV(e.Data);
     this.DataArrival(msg, CSS.IM.Library.Class.NatClass.FullCone, e.IP, e.Port);
 }
        /// <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侦听
                CSS.IM.Library.Class.msgAV msg = new CSS.IM.Library.Class.msgAV();
                msg.InfoClass = (byte)CSS.IM.Library.Class.ProtocolAVTransmit.GetUDPWANInfo;//通信协议
                this.sockUDP1.Send(_serverIp, _serverUDPPort, msg.getBytes());//获得文件传输套接字的广域网UDP端口
                //Calculate.WirteLog("对方要求采用广域网方式通信");
            }

            if (!timersUdpPenetrate.Enabled)//如果未握手,则开始握手
                timersUdpPenetrate.Enabled = true;//开始向对方UDP端口握手(打洞),如果成功,表示可以进行UDP通信
        }
 /// <summary>
 /// 发送视频数据到对方
 /// </summary>
 /// <param name="data">视频数据</param>
 public void SendVideo(byte[] data)
 {
     CSS.IM.Library.Class.msgAV msg = new  CSS.IM.Library.Class.msgAV();
     msg.InfoClass = (byte)CSS.IM.Library.Class.ProtocolAVTransmit.GetVideoData;
     msg.DataBlock = data ;
     this.sendData(msg);
 }
        /// <summary>
        /// 发送视频图像头信息到对方
        /// </summary>
        /// <param name="BITMAPINFOHEADER">视频图像头信息</param>
        public void SendBITMAPINFOHEADER(BITMAPINFOHEADER BITMAPINFOHEADER)
        {
            CSS.IM.Library.Class.BitmapInfoHeader bitmapInfoHeader = new CSS.IM.Library.Class.BitmapInfoHeader();
            bitmapInfoHeader.biBitCount = BITMAPINFOHEADER.biBitCount;
            bitmapInfoHeader.biClrImportant = BITMAPINFOHEADER.biClrImportant;
            bitmapInfoHeader.biClrUsed = BITMAPINFOHEADER.biClrUsed;
            bitmapInfoHeader.biCompression = BITMAPINFOHEADER.biCompression;
            bitmapInfoHeader.biHeight = BITMAPINFOHEADER.biHeight;
            bitmapInfoHeader.biPlanes = BITMAPINFOHEADER.biPlanes;
            bitmapInfoHeader.biSize = BITMAPINFOHEADER.biSize;
            bitmapInfoHeader.biSizeImage = BITMAPINFOHEADER.biSizeImage;
            bitmapInfoHeader.biWidth = BITMAPINFOHEADER.biWidth;
            bitmapInfoHeader.biXPelsPerMeter = BITMAPINFOHEADER.biXPelsPerMeter;
            bitmapInfoHeader.biYPelsPerMeter = BITMAPINFOHEADER.biYPelsPerMeter;

            CSS.IM.Library.Class.msgAV msg = new CSS.IM.Library.Class.msgAV();
            msg.InfoClass = (byte)CSS.IM.Library.Class.ProtocolAVTransmit.GetBITMAPINFOHEADER;
            msg.DataBlock = bitmapInfoHeader.getBytes();
            this.sendData(msg);
        }