我在這個網站上讀過很多關於如何在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