2

I've implemented a C native function with for android NDK, to send UDP packets. I have a working receiver but i seem to get nothing when i use the sender.

  • How can i get more info from the return value of sendto? I'm having a hard time debugging native functions - no "debug step mode"
  • can anyone see anything wrong about the sender code? is there something im not doing right?

Thanks!

jstring
Java_com_example_adhocktest_SenderUDP_SendUdpJNI( JNIEnv* env,
                                                  jobject thiz, jstring ip, jstring message)
{
    int PORT = 8888;

    int i;
    int sock_fd;

    char *_ip = (*env)->GetStringUTFChars(env, ip, 0);
    char *send_buf = (*env)->GetStringUTFChars(env, message, 0);

    ////////////////
    //////// create socket
    ////////////////
    if (( sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
        return (*env)->NewStringUTF(env,"Cannot create socket");
    }

    struct sockaddr_in myaddr;

    ////////////////
    //////// send
    ////////////////
    struct sockaddr_in servaddr;

    memset((char*)&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = 8888;

    if ((inet_aton(_ip,&servaddr.sin_addr)) == 0) {
        return (*env)->NewStringUTF(env,"Cannot decode IP address");
    }

    int retval = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr*)&servaddr, sizeof(servaddr));
        close(sock_fd);

        char str[100];

    if ( retval < 0) {

            sprintf(str, "sendto failed with %d", retval);
    } else {
            sprintf(str, "sendto success with %d", retval);
        }
        return (*env)->NewStringUTF(env,str);
}
Sitansu
  • 3,225
  • 8
  • 34
  • 61
Wakaka
  • 51
  • 1
  • 7
  • 1
    use logging to logcat: http://stackoverflow.com/questions/4629308/any-simple-or-easy-way-to-debug-android-ndk-code – marcinj Dec 30 '13 at 17:24
  • I did use logcat but i got a correct return value from sendto(). ---Found the solution----- servaddr.sin_port = htons(8888); I dont fully understand the whole htons thing so if anyone could elaborate it would be lovely. – Wakaka Dec 30 '13 at 18:07

2 Answers2

2

The problem in the code was this line

servaddr.sin_port = 8888;

the correct line would be

servaddr.sin_port = htons(8888);

the reason for this was explained here by

bornruffians:

" htons() stands for "host-to-network short". On a given platform (called the host), it converts the endianness of a short (16-bit generally) integer to the endianness required for sending on the network (generally big endian).

sendto() returns the number of bytes sent. You should check that retval is the string length of your 'send_buf' variable, not just a positive value."

Thanks all for your help, Ben.

Community
  • 1
  • 1
Wakaka
  • 51
  • 1
  • 7
0

If it's still not working, did you give your app the necessary permissions for manipulating sockets?

<uses-permission android:name="android.permission.INTERNET" />

htons() stands for "host-to-network short". On a given platform (called the host), it converts the endianness of a short (16-bit generally) integer to the endianness required for sending on the network (generally big endian).

sendto() returns the number of bytes sent. You should check that retval is the string length of your 'send_buf' variable, not just a positive value.

bjornruffians
  • 671
  • 5
  • 16
  • As i said htons solved the problem. i had the right permissions i was just setting the port number without taking care of endians. Thanks for your explanation of htons() function. – Wakaka Jan 01 '14 at 07:37