我在这个网站上读过很多关于如何在Android中接收UDP数据包的文章。但是,这些都不适合我!Android的UDP通信
一些基本知识:
我测试我的HTC不可思议的(Android 2.2的)在3G(没有WiFi或其他任何东西)上运行。这里没有模拟器参与。
我的代码很简单:
- 我的服务器(在我的电脑上运行)正在监听UDP通信端口8752.
- 我的Android应用程序打开一个随机端口一个DatagramSocket和发送报文我的服务器与此端口。
- 然后我保存这些信息(InetAddress形成接收的数据包和在数据包中找到的端口)。
- 我尝试从我的服务器(再次,在我的PC)发送一个UDP数据包到我的Android应用程序(在我的手机上运行),它不起作用。
//Server code to initialize the UDP socket (snippet)
public void init() {
datagram_server_socket = new DatagramSocket(port,local_addr);
datagram_server_socket.setSoTimeout(1000);
}
//片段上的Android应用程序代码,发送数据包到服务器
public void connect() {
Random r = new Random(System.currentTimeMillis());
int udp_port = 0;
while(true){
try {
udp_port = r.nextInt(1000)+8000;
udp_port = 8000;
comm_skt = new DatagramSocket(udp_port);
Log.i("ServerWrapper", "UDP Listening on port: " + udp_port);
break;
} catch(SocketException e) {
Log.e("ServerWrapper", "Could not bind to port " + udp_port);
}
}
byte[] sdata = new byte[4+tid.length];
i = 0;
sdata[i++] = (byte)(0XFF&(udp_port>>24));
sdata[i++] = (byte)(0XFF&(udp_port>>16));
sdata[i++] = (byte)(0XFF&(udp_port>>8));
sdata[i++] = (byte)(0XFF&(udp_port));
for(byte b: tid){
sdata[i++] = b;
}
DatagramPacket pkt = new DatagramPacket(sdata, sdata.length,
InetAddress.getByName(hostname), port);
comm_skt.send(pkt);
}
//Server's UDP socket listening code
public void serverUDPListener() {
try {
datagram_server_socket.receive(rpkt);
int port = 0;
byte[] rdata = rpkt.getData();
port += rdata[0]<<24;
port += rdata[1]<<16;
port += rdata[2]<<8;
port += (0XFF)&rdata[3];
byte[] tid = new byte[rdata.length];
for(int i = 4; i < rdata.length && rdata[i] > 0; i++) {
tid[i-4] = rdata[i];
}
String thread_id = new String(tid).trim();
for(int i = 0; i < threads.size(); i++) {
ClientThread t = threads.get(i);
if(t.getThreadId().compareTo(thread_id) == 0) {
t.setCommSocket(rpkt, port);
} else {
System.err.println("THREAD ID " + thread_id + " COULD NOT BE FOUND");
}
}
} catch (IOException e) {
if(!(e instanceof SocketException) && !(e instanceof SocketTimeoutException))
log.warning("Error while listening for an UDP Packet.");
}
}
//Corresponds to the setCommSocket call above to save the IP and Port of the incoming UDP packet on the server-end
public void setCommSocket(DatagramPacket pkt, int port) {
comm_ip = pkt.getAddress();
comm_port = pkt.getPort(); //Try the port from the packet?
}
//Sends an UDP packet from the SERVER to the ANDROID APP
public void sendIdle() {
if(comm_ip != null) {
System.err.println("Sent IDLE Packet (" + comm_ip.getHostAddress() + ":" + comm_port + ")");
DatagramPacket spkt = new DatagramPacket(new byte[]{1, ProtocolWrapper.IDLE}, 2, comm_ip, comm_port);
DatagramSocket skt;
try {
skt = new DatagramSocket();
skt.send(spkt);
} catch (Exception e) {
e.printStackTrace();
}
}
}
现在我已经硬编码端口我的应用程序使用到8000.但是,奇怪的是,每次我测试我的程序(并查看保存在我的服务器上的IP /端口),该数据包来自的端口始终是33081.我有AA线不断地监听UDP流量在我的Android应用程序,但该代码永远不会执行通过的“接收(数据包)”部分:
public void AndroidUDPListener() {
while(true) {
synchronized(stop) {
if(stop) return;
}
byte[] recieve_data = new byte[64];
DatagramPacket rpkt = new DatagramPacket(recieve_data, recieve_data.length);
try {
if(comm_skt == null)
continue;
comm_skt.receive(rpkt);
byte[] data = rpkt.getData();
switch(data[1]) {
case IDLE:
if(ocl != null) ocl.onCompletion(null);
break;
case KEEP_ALIVE:
break;
}
} catch (Exception e) {
if(!(e instanceof SocketException) && !(e instanceof SocketTimeoutException))
Log.w("ServerWrapper", "Error while listening for an UDP Packet.");
}
}
}
有谁看到一个问题在我的代码?或者是否有一些需要先在我的应用程序上设置的权限/设置?我启用了互联网通信。
实施例产量(使用的端口从所述数据包的getPort()):
Android应用 - 现在监听UDP通信端口8000
Android应用 - 发送分组到服务器
服务器 - 从XXXXXX收到的数据包:33081
服务器 - 将IDLE数据包发送到XXXXXX:33081
实施例产量(使用的端口从分组数据):
Android应用 - 现在监听UDP通信端口8000
Android应用 - 发送分组到服务器
服务器 - 从XXXXXX接收的数据包:8000
服务器 - 发送空闲分组到XXXXXX:8000
Android应用程序永远不会使用任何端口接收任何UDP通信。
你能得到这个工作在两个台式机/笔记本电脑(没有你的Android手机)?如果您可以将手机作为问题消除,那么我们可以认为这是您的代码问题。 – Kiril 2011-05-05 23:40:09
我能够将手机放在我的WiFi网络上,并以这种方式获得UDP数据包(使用直接IP作为主机名,使用外部DNS名称不起作用)。我还让我的朋友测试了我编写的一个程序,用于在家中模拟Android的应用程序网络调用(使用外部DNS名称),并且它工作正常(在进行端口转发并强制使用非随机UDP端口之后)。我希望这能澄清问题是我的代码。 – someone1 2011-05-06 03:37:41