void ReceiveMessage()
         {
             //UdpClientB = new UdpClient(portclient); //B开启的端口号 
             //remotePoint = new IPEndPoint(IPAddress.Any, 0);
             int recv;
             byte[] bytes = new byte[1024];  
 
             IPEndPoint ipt = new IPEndPoint(IPAddress.Any, 13000);
             Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
             server.Bind(ipt);
 
             while (true)
             {
                 try
                 {
                     IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
                     EndPoint Remote = (EndPoint)(sender);
                     recv = server.ReceiveFrom(bytes, ref Remote);
 
                     MessagePP com = (MessagePP)DeserializeObject(bytes);
                     if (com.command == 0)
                     {
                         ReceivedACK = true;
                     }
                     else
                     {
                         //收的都是图片了
                         MessageBox.Show("B已经收到了A发来的图片消息了");
                     }
 
                 }
                 catch
                 {
 
                 }
             }
         }
单步调试,到了红色的那行代码处,没有继续往下运行了.....求助...正在弄UDP打洞,这个为Client,监听着自己这边的一个端口,然后要得到其他Client发过来的数据

解决方案 »

  1.   

    我发现了......打洞发出来的send
    好像另一个Client不能收到消息,所以停在那里了
    哈哈,贴一下这两端代码哈...大家来看看呗!!
      

  2.   

    A, B的ip都用中间的server(服务器)来做中转,得到对方的ip都放在holeIp里面,这里没问题
    #region 打洞A->B的函数
            public UdpClient UdpClientA;
            /// <summary>
            /// 用来发送图片过去给B和打洞
            /// </summary>
            void RunHole()
            {
                //holeip     ---   为得到的B的公网ip, 端口默认用13000
                //先往B打洞...,打洞的时候要设置一个最大的打洞次数...如果打通了就不再打了...至于打通没打通,就看接收线程有没有接收到命令为0的包            UdpClient UdpSendA = new UdpClient();
                IPEndPoint sendIp = new IPEndPoint(IPAddress.Parse(holeip), 13000);
                
                while (true)
                {
                    //sendA.Connect(remote);
                    if (ReceivedACK == false)
                    {
                        int i;
                        int j;
                        int flag = 0;
                        MessagePP sendBag = new MessagePP();
                        sendBag.command = 0;
                        Byte[] buffer = SerializeObject(sendBag);
                        for (i = 0; i < MaxHole; ++i)
                        {
                            UdpSendA.Send(buffer, buffer.Length, sendIp);
                            for (j = 0; j < 10; ++j)
                            {
                                if (ReceivedACK == true)
                                {
                                    flag = 1;   //标志flag = 1;然后跳出来之后,再判断如果flag = 1的话再跳出一个循环
                                    break;
                                }
                                else
                                {
                                    Thread.Sleep(300);  //线程稍微睡一下,等一下那边接收线程看对方打洞过来了没
                                }
                            }
                            if (flag == 1)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        //发送视频图片了
                        MessageBox.Show("B已经接到了A的其他内容的信息了");
                    }
                }
            }
            /// <summary>
            /// 用来接收B发来图片和接收那个打洞消息
            /// </summary>
            void SuccedHole()
            { 
                //来监听自己开放的端口porthost,看B发了什么东西过来,如果是打洞消息的话标志一下B向我打了洞
                
                UdpClientB = new UdpClient(24000);
                IPEndPoint senderRemote = null;            while (true)
                {
                    if (UdpClientB.Available != 0)
                    {
                        try
                        {
                            Byte[] buffer = UdpClientB.Receive(ref senderRemote);
                            MessagePP com = (MessagePP)DeserializeObject(buffer);
                            if (com.command == 0)
                            {
                                ReceivedACK = true;
                            }
                            else
                            {
                                //收的都是图片了
                                MessageBox.Show("B已经收到了A发来的图片消息了");
                            }                    }
                        catch (Exception ex)
                        {
                            string st = ex.Message;
                        }
                    }
                }
            }
            #endregion        #region 打洞B->A的函数        public UdpClient UdpClientB;
            public IPEndPoint remotePoint;
            public IPEndPoint otherPoint;
            /// <summary>
            /// 用来发送图片过去给A和打洞
            /// </summary>
            void SendMessage()
            { 
                //ip已经传进来了,存放在holeip,然后端口默认用24000,ReceivedACK一开始等于false,直到接收到对方发来的东东,之后变成true            UdpClient UdpSendB = new UdpClient();
                IPEndPoint sendIp = new IPEndPoint(IPAddress.Parse(holeip), 24000);
                while (true)
                {
                    if (ReceivedACK == false)
                    {
                        int i;
                        int j;
                        int flag = 0;
                        MessagePP sendBag = new MessagePP();
                        sendBag.command = 0;
                        Byte[] buffer = SerializeObject(sendBag);
                        for (i = 0; i < MaxHole; ++i)
                        {
                            UdpSendB.Send(buffer,buffer.Length,sendIp);
                            for (j = 0; j < 10; ++j)
                            {
                                if (ReceivedACK == true)
                                {
                                    flag = 1;   //标志flag = 1;然后跳出来之后,再判断如果flag = 1的话再跳出一个循环
                                    break;
                                }
                                else
                                {
                                    Thread.Sleep(300);  //线程稍微睡一下,等一下那边接收线程看对方打洞过来了没
                                }
                            }
                            if (flag == 1)
                            {
                                break;
                            }
                        }
                    }
                    else
                    {
                        //发送视频图片了
                        MessageBox.Show("B已经接到了A的其他内容的信息了");
                    }
                }
            }
            /// <summary>
            /// 用来接收A发来图片和接收那个打洞消息
            /// </summary>
            void ReceiveMessage()
            {
                IPEndPoint senderRemote = null;
                UdpClientA = new UdpClient(13000);      //B监听13000端口
                while (true)
                {
                    //Socket clientb = s.Accept();
                    if(UdpClientA.Available != 0)
                    {
                        try
                        {
                            Byte[] buffer = UdpClientA.Receive(ref senderRemote);                        MessagePP com = (MessagePP)DeserializeObject(buffer);
                            if (com.command == 0)
                            {
                                ReceivedACK = true;
                            }
                            else
                            {
                                //收的都是图片了
                                MessageBox.Show("B已经收到了A发来的图片消息了");
                            }                    }
                        catch (Exception ex)
                        {
                            string st = ex.Message;
                        }
                    }
                }
            }
            #endregion
      

  3.   


    哇...我是在我自己的计算机上测试的...服务器 和 A 还有B 都是我自己的电脑上测试
    这样不行么???我现在察觉是不是这样:
    A -> Server: 这时候 Server记录下A的IP和port(把A和Server连上的这个ip+port发给B,而我上面UDP是自己指定A的port,然后A去"监听")然后听你这么一说 我又迷糊了...呵呵,这个东东 我做了两天了...都不知道是哪里出问题....
    哈哈,你如果有空的话 麻烦花你一些时间 给我回复下哈...如果按你说的那样,那我在同一个局域网是这样做,那如果不同局域网,代码就要改了??还是用一样的代码也可以??
      

  4.   

    所有的打洞都是会对对方的本地地址和公网地址分别打洞的,因为作为通用软件预先无法判断两个客户端是否在同一局域网内。
    其实你到处找代码的时间内,不如花二十分钟看一下《Windows网络与通信程序设计》的相关部分,再花一小时看一下《Tcp/Ip协议详解》中关于可靠性的相关章节,你用UDP传输文件时会参考到Tcp保证可靠性的做法。
      

  5.   


    Windows网络与通信程序设计 已经看了..
    不知道是因为我理解能力不够好还是怎么的...我觉得他的意思就是 在server处把A的公网ip + port发给B,然后B往A打洞,之后通知Server,再让server通知A去往B打洞...可这样写起来就报错了....嘿嘿,以为别人前人写过的代码 直接copy,会快点!!!现在很急~~~
    《Tcp/Ip协议详解》中关于可靠性的相关章节,等我先打洞打通了..再考虑传输完整性的问题哈!!
    【ps: 我还是觉得我贴出来的那段代码好像可以】
    你A把说外网和内网都发给B之后,那B要怎么去连它???
    嘿嘿....如果可以最好贴一下 伪代码 或者源代码哈......
    比较笨哈,这样理解不了哈~~
      

  6.   


    嘿嘿..又要打搅你了...
    那个先 用内网IP打洞,再用外网IP打洞,
    1.比如A的内网IP是192.168.1.55,记录下来传到B,那个传过去的port是自己设定的么?
    2.到外网打洞的时候,A的外网IP:PORT(通过Server得到的),然后UdpClient,不是要监听它的一个端口么,那是不是要从Server那里在拿自己的外网Port回来绑定???
      

  7.   

    同一个NAT下已经打通了....
    现在不同的NAT还没开始打!!因为那个PORT的问题,求速速指点哈》。。