Android NDK socket connect() returning 0 when it should fail whilst on 3g

匿名 (未验证) 提交于 2019-12-03 00:44:02

问题:

I have written a socket in the android NDK and a server in c. It is able to connect to the server fine. However if the server is down or I try to get it to connect to a different random IP the call to connect still returns 0 when it should return -1.

Here is the code for the client:

#include <stdio.h> #include <jni.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <android/log.h> #include <unistd.h>  #define APPNAME "MyApp" #define logcat(...)  __android_log_print(ANDROID_LOG_VERBOSE, APPNAME, __VA_ARGS__)   int createSocket() {     int sockFD;     if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {         logcat("Unable to create socket");         return -1;     }      logcat("Socket created: %i", sockFD);     return sockFD;   } JNIEXPORT jint JNICALL Java_myapp_client( JNIEnv* env,                                       jobject thiz ) {     struct sockaddr_in server;     int sockFD, new_socket;     char * message;     if ((sockFD = createSocket()) < 0) {         return -1;     }     server.sin_family = AF_INET;     server.sin_addr.s_addr = inet_addr(server ip);     server.sin_port = htons(8888);     new_socket = connect(sockFD, (struct sockaddr *)&server, sizeof(server));     logcat("Connect return value: %i", new_socket);      int rtn = recv(sockFD, message, sizeof(char), 0);     logcat("Message: %i", rtn);      close(sockFD);      return 1; } 

A valid descriptor is made for the socket, the return values for connect and recv are zero when I run this without my server running. Might be worth noting the android device is connected to the internet over mobile internet.

回答1:

I removed android specific parts

#include <stdio.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h>   int createSocket() {     int sockFD;     if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {         printf("Unable to create socket");         return -1;     }      printf("Socket created: %i", sockFD);     return sockFD;   } int main() {     struct sockaddr_in server;     int sockFD, new_socket;     char * message;     if ((sockFD = createSocket()) < 0) {         return -1;     }     server.sin_family = AF_INET;     server.sin_addr.s_addr = inet_addr("127.0.0.1");     server.sin_port = htons(8888);     new_socket = connect(sockFD, (struct sockaddr *)&server, sizeof(server));     printf("Connect return value: %i", new_socket);      int rtn = recv(sockFD, message, sizeof(char), 0);     printf("Message: %i", rtn);      close(sockFD);      return 1; } 

This works as expected. Try it yourself by connecting to 127.0.0.1. If there is no server running on your host machine then it will fail to connect (connect will return -1 and errno will be set appropriately).

Make sure the IP address you are using for connection is really pointing to your server.

Also there is a problem in recv:

int rtn = recv(sockFD, message, sizeof(char), 0); 

Variable message is a pointer that has not be assigned to any memory (it contains some stack garbage value) and you are overwriting it. See manual for recv (2).

To fix this you should either assign your pointer to some allocated memory:

message = malloc(1); //char is always a single byte 

or use stack instead of heap for storing the message byte:

char message; ... int rtn = recv(sockFD, &message, sizeof(char), 0); 

I assumed your message is always a single byte.

Keep in mind that in here:

printf("Message: %i", rtn); 

you are printing the return code not the actual message.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!