我目前正在为我的udp服务器在Android上实现udp孔穿孔。事情应该这样运作:
下面是我当前的客户端实现(Android):
//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):
//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数据包转发到我的计算机
发布于 2015-09-07 17:08:49
不同的套接字绑定到不同的专用端口,并使用NAT的不同公共端口。您正在接收和发送通过不同的套接字。使用接收数据的相同套接字发送。否则,您的发送套接字将使用路由器的不同公共端口向客户端NAT发送数据。这个包您的客户端NAT丢弃,因为它来自相同的IP,但未知端口。
https://stackoverflow.com/questions/32397756
复制相似问题