Android UDP Communication

I've read many posts on this site on how to receive UDP packets in Android. However, none of this is working for me!

Some basics:

I am testing on my HTC Incredible (Android 2.2) running on 3G (not wifi or anything else). No emulators are involved here.

My code is simple:

  1. My server (running on my PC) is listening for UDP traffic on port 8752.
  2. My Android application opens a DatagramSocket on a random port and sends a packet to my server with this port.
  3. I then save this information (the InetAddress form the received packet and the port found within the packet).
  4. I try to send an UDP packet from my server (again, on my PC) to my Android app (running on my phone) and it does NOT work.
//Server code to initialize the UDP socket (snippet)
public void init() {
    datagram_server_socket = new DatagramSocket(port,local_addr);
    datagram_server_socket.setSoTimeout(1000);
}

//Snippet of code on the ANDROID APP that sends a packet to the server

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();
        }
    }
}

Right now I've hard coded the port my application uses to 8000. However, what's odd is that EVERYTIME I test my program (and view the IP/Port that is saved on my server), the port the packet came from is always 33081. I have a a thread constantly listening for UDP traffic in my Android App but the code never executes passed the "receive(packet)" part:

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.");
        }
    }
}

Does anyone see an issue in my code? Or is there some permission/settings I need to set on my application first? I have internet communication enabled.

Example Output (using the port from the packet getPort()):

Android App - Now listening for UDP traffic on port 8000

Android App - Sending packet to server

Server - Received packet from XXXXXX:33081

Server - Sending IDLE packet to XXXXXX:33081

Example Output (using the port from the packet data):

Android App - Now listening for UDP traffic on port 8000

Android App - Sending packet to server

Server - Received packet from XXXXXX:8000

Server - Sending IDLE packet to XXXXXX:8000

The Android App never receives any UDP traffic from using either of the ports.

7
задан Tomik 19 October 2012 в 22:52
поделиться