native C socket/connect problems

1,338 views
Skip to first unread message

Fred Templin

unread,
Sep 22, 2015, 11:10:34 PM9/22/15
to android-ndk
Hello,

I am using NDK with Android Studio 14.1 Beta. I have a tablet that is running lollipop
(Android v. 5.0.1), and I am building for API 21. My code consists of a simple java
front end derived from the ToyVpn sample code that comes with the SDK. The java
code calls a C library that I developed, debugged and tested under Linux.

In the C library, I am using the standard networking socket API. I successfully create
a socket in the main routine as:

  addr_fd = socket(AF_INET, SOCK_DGRAM, 0);

where "addr_fd" is a global integer. Then, in a signal handler routine I connect to
the socket as follows:

  struct sockaddr_in addr;

  addr.sin_family = AF_INET;
  addr.sin_port = port;  /* a valid UDP port number */
  addr.sin_addr = addr; /* a valid IPv4 address */
  if (connect(addr_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
    syslog(LOG_ERR, "connect failed: %s", strerror(errno));
  else
    syslog(LOG_ERR, "connect succeeded");

When I run the code, it always reports "connect failed: Network is Unreachable"
even though the network was set up correctly before I ran the app. After
terminating the app, however, I also get "Network Unreachable" when I try
to ping addr with a different app even though the pings succeeded before I
ran my app. So, my app is clearly messing up the network somehow in
addition to not being able to connect. Any ideas on how to fix this?

Thanks - Fred
 

 

J Decker

unread,
Sep 22, 2015, 11:33:25 PM9/22/15
to andro...@googlegroups.com
sure you have network permissions in your manifest?
> --
> You received this message because you are subscribed to the Google Groups
> "android-ndk" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to android-ndk...@googlegroups.com.
> To post to this group, send email to andro...@googlegroups.com.
> Visit this group at http://groups.google.com/group/android-ndk.
> For more options, visit https://groups.google.com/d/optout.

Fred Templin

unread,
Sep 23, 2015, 4:28:36 PM9/23/15
to android-ndk
Thanks for the reply. In my file named ./app/src/main/AndroidManifest.xml, I have:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>

Is that the correct Manifest file, or do I need to add these lines somewhere else?

In my app, I am running the following native C code:

    while (1) {

        int fd;

        struct sockaddr_in addr;


        fd = socket (AF_INET, SOCK_DGRAM, 0);

        if (fd < 0) {

                syslog(LOG_ERR, "socket: %s\n", strerror(errno));

                break;

         }

        addr.sin_family = AF_INET;

        addr.sin_port = 0;

        addr.sin_addr.s_addr = pr->ip;

        if (connect (fd, (struct sockaddr*)&addr, sizeof(addr))== 0)

                syslog(LOG_ERR, "socket connect works!\n");

        else

                syslog(LOG_ERR, "socket connect fails: %s\n", strerr(errno));

        close (fd);

        sleep(2);

    }


When the code runs, it prints:


    socket connect works!

    socket connect fails: Network is unreachable

    socket connect fails: Network is unreachable

    socket connect fails: Network is unreachable

    ...


In other works, the connect works the first time then fails all subsequent times. As

a side effect of running this code in my app, the networking system in the entire

tablet seems to get destroyed. In particular, when I try to ping from a terminal

emulator window I get "Network is Unreachable".


This code works under Linux. Is there something I am either forgetting or doing

wrong under Android?


Thanks - Fred


Fred Templin

unread,
Sep 23, 2015, 4:28:36 PM9/23/15
to android-ndk
About network permissions in the manifest, I am a little bit confused as to *which*
file to add the permissions to. I see the following files as possible candidates:

(1)  ./app/build.gradle
(2)  ./app/src/main/AndroidManifest.xml
(3)  ./app/build/intermediates/manifest/androidTest/all/debug/AndroidManifest.xml
(4)  ./app/build/intermediates/manifests/full/all/debug/AndroidManifest.xml

I have done nothing to (1). In (2), I have added the following lines:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>

After building my project in Android Studio, I note that the "uses-permission" lines
show up in (4) but do not show up in (3). I assume (3) and (4) are auto-generated.

Am I somehow missing something? The existence of file (3) with no permissions
worries me. Could that be the reason the network is failing?

Thanks - Fred


On Tuesday, September 22, 2015 at 8:33:25 PM UTC-7, J Decker wrote:

J Decker

unread,
Sep 23, 2015, 4:34:19 PM9/23/15
to andro...@googlegroups.com
Okay I don't think port 0 is a valid port.
and you don't bind your socket to any port so there's no way it can
send or receive (having no src or dest for the other side to send to)

http://www.cs.odu.edu/~cs476/fall03/lectures/sockets.htm

Fred Templin

unread,
Sep 24, 2015, 10:40:19 AM9/24/15
to android-ndk
Another update. In the C code I provided in the previous message, I inserted the
line: "sleep (1)" before the first socket/connect invocation. When I did that, I got
"socket connect fails: Network is unreachable" in the very first attempt. So, the
condition appears to be timing related.

So, somehow the way in which my native C code is being invoked is trashing
the network within a short amount of time after startup. So, the condition does
not appear to be related to socket/connect directly, but is somehow related to
the very invocation of the code. Ideas are welcome!

Thanks - Fred 

Fred Templin

unread,
Sep 24, 2015, 10:40:22 AM9/24/15
to android-ndk
Many thanks for the idea. I tried changing the port to "addr.sin_port = htons(8060);"
but there was no change in the behavior - still getting success on the first connect
and "network is unreachable" on all subsequent connects. I am not using the socket
to send or receive any packets (only to discover the address of the outgoing
interface to be used to send to the destination) so setting port to 0 should be OK,
and works fine on linux.

It worries me that the automatically generated AndrodManifest.xml file that
shows up in "./app//build/intermediates/manifest/androidTest/all/debug" does
not have any of the "uses-permission" lines that the other AndroidManifest.xml
files have. Could this be the problem? And, what do I need to do to make
the "uses-permission" lines show up there?

Thanks - Fred
Reply all
Reply to author
Forward
0 new messages