日期:2014-05-20  浏览次数:20773 次

Java 实现UDP打洞
首先向各位大哥大姐求一个UDP打洞的例子。
我自己写了一个。可是怎么做都不成功。我把代码发出来,大家帮忙看看有什么问题。在这里先谢谢各位了!
Java code

//服务器端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class TestServer 
{

    public static void main(String[] args) throws IOException 
    {
        DatagramSocket chatUDPSocket = new DatagramSocket(8888);
        while(true)
        {
            byte[] recvBuf = new byte[100];
            DatagramPacket recvPacket = new DatagramPacket(recvBuf , recvBuf.length);
            chatUDPSocket.receive(recvPacket);
            System.out.println(recvPacket.getSocketAddress().toString());
        }
    }

}



Java code

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class TestClient 
{

    public static void main(String[] args) throws IOException 
    {
        DatagramSocket clienttoclient = new DatagramSocket();
        String sendStr = "hello";
        byte[] sendBuf = sendStr.getBytes();
        InetAddress addr = InetAddress.getByName("125.34.69.243");
        int port = 8888;
        DatagramPacket sendPacket 
            = new DatagramPacket(sendBuf ,sendBuf.length , addr , port);
        clienttoclient.send(sendPacket);
        
        new ReceiveMessages(clienttoclient);
        
        System.out.println("输入要联系的IP地址");
        Scanner in = new Scanner(System.in);
        String userIP = in.next();
        System.out.println("输入要联系的端口号");
        int userPort = in.nextInt();
        
        byte[] chatsendBuf = "hello".getBytes();
        InetAddress chatAddr = InetAddress.getByName(userIP);
        DatagramPacket chatsendPacket = new DatagramPacket(chatsendBuf,chatsendBuf.length,chatAddr,userPort);
        clienttoclient.send(chatsendPacket);
        System.out.println("test");
    }

}

class ReceiveMessages extends Thread
{
    private DatagramSocket clienttoclient;
    public ReceiveMessages(DatagramSocket clienttoclient)
    {
        this.clienttoclient = clienttoclient;
        this.start();
    }
    public void run()
    {
        System.out.println("启动监听客户端接收客户端发送的消息");
        byte[] recvBuf = new byte[100];
        DatagramPacket recvPacket
            = new DatagramPacket(recvBuf , recvBuf.length);
        try {
            clienttoclient.receive(recvPacket);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String recvStr = new String(recvPacket.getData() , 0 ,recvPacket.getLength());
        System.out.println("收到:" + recvStr);
    }
}




------解决方案--------------------
如果你客户端在公网上,那么应该一定可以收到才对。

你可以先测试一下TestClient中new DatagramSocket()时先指定一个固定的端口,
这样可以不管服务器。可以直接相互知道地址,看看是否可以正常发送。
------解决方案--------------------
我觉得你可以考虑用抓包工具先看看包是否正常发出去了,还有包的内容是不是和你设计的一样