首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android上的UDP孔冲压

Android上的UDP孔冲压
EN

Stack Overflow用户
提问于 2015-09-04 12:11:21
回答 1查看 2.1K关注 0票数 6

我目前正在为我的udp服务器在Android上实现udp孔穿孔。事情应该这样运作:

  1. 客户端( nat;可能是3G,..)向服务器发送DatagramPacket (服务器具有公共ip;端口也已知为45555)。客户端重复发送具有给定延迟的数据报。
  2. 一旦服务器接收到数据报,它就每500 it发回一次数据报(“信号”)。
  3. 如果打孔成功,客户应该接收到这些信号。

下面是我当前的客户端实现(Android):

代码语言:javascript
运行
复制
    //in onCreate()
    DatagramSocket socket = new DatagramSocket(46222);
    socket.setSoTimeout(2000);
    final Thread t = new Thread(new Runnable(){

        @Override
        public void run() {
            int delay = Integer.parseInt(e2.getText().toString());//e1 and e2 are EditTexts
            String ip = e1.getText().toString();
            try {
                DatagramPacket packet = new DatagramPacket(new byte[1],1, InetAddress.getByName(ip), 45555);
                while(!cleanUp){//cleanUp is set to true in onPause()
                    lock.lock(); //Lock lock = new ReentrantLock();
                    socket.send(packet);
                    lock.unlock();
                    Thread.sleep(delay);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                if(socket!=null)
                    socket.close();
            }
        }

    });
    final Thread t2 = new Thread(new Runnable(){

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                DatagramPacket packet = new DatagramPacket(new byte[1],1);
                while(!cleanUp){
                    lock.lock();
                    try{
                        socket.receive(packet);
                    }catch(SocketTimeoutException e){
                        lock.unlock();
                        Thread.sleep(15);
                        continue;
                    }
                    lock.unlock();
                    final String s = tv.getText().toString()+"signal\n";
                    MainActivity.this.runOnUiThread(new Runnable(){

                        @Override
                        public void run() {
                            tv.setText(s);//tv is a TextView
                        }

                    });
                    Thread.sleep(10);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            finally{
                if(socket!=null)
                    socket.close();
            }
        }

    });
    //start both threads

以下是服务器端实现(Java):

代码语言:javascript
运行
复制
//int static void main(String[] args):
final Thread t = new Thread(new Runnable(){

        @Override
        public void run() {
            try {
                DatagramPacket packet = new DatagramPacket(new byte[1],1, addr, port);
                DatagramSocket socket = new DatagramSocket();
                System.out.println("send");
                while(true){
                    socket.send(packet);
                    Thread.sleep(500);
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    });
    final Thread t2 = new Thread(new Runnable(){

        @Override
        public void run() {
            try {
                DatagramPacket packet = new DatagramPacket(new byte[1],1);
                DatagramSocket socket = new DatagramSocket(45555);
                socket.receive(packet);
                addr = packet.getAddress(); //private static field InetAddress addr
                port = packet.getPort();
                System.out.println(addr+":"+ packet.getPort()); //field int port
                t.start();
                while(true){
                    socket.receive(packet);
                    System.out.println("idle");
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    });
    t2.start();

当客户端和服务器在同一个专用网络中时,一切都可以工作。为了模仿公共服务器,我在我的计算机上运行服务器端代码,并在我的路由器上设置一个端口(它有一个公共ip)*。客户端将将其数据包发送到路由器的公共ip。但在这两种情况下(我的智能手机通过我的wlan网络/ 3G或E连接到互联网)没有接收到信号(服务器接收客户端的数据报)

那么,为什么打孔过程不能工作呢?

问候

*:路由器将把发送到其端口45555的任何udp数据包转发到我的计算机

EN

回答 1

Stack Overflow用户

发布于 2015-09-07 17:08:49

不同的套接字绑定到不同的专用端口,并使用NAT的不同公共端口。您正在接收和发送通过不同的套接字。使用接收数据的相同套接字发送。否则,您的发送套接字将使用路由器的不同公共端口向客户端NAT发送数据。这个包您的客户端NAT丢弃,因为它来自相同的IP,但未知端口。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32397756

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档