Android NDK套接字connect()在3g时失败时返回0

我在android NDK中编写了一个套接字,在c中编写了一个服务器。 它能够很好地连接到服务器。 但是,如果服务器已关闭或我尝试将其连接到另一个随机IP,则当它应返回-1时,对connect的调用仍会返回0。

以下是客户端的代码:

#include  #include  #include  #include  #include  #include  #include  #include  #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; } 

为套接字创建了一个有效的描述符,当我在没有运行服务器的情况下运行它时,connect和recv的返回值为零。 可能值得注意的是Android设备通过移动互联网连接到互联网。

我删除了android特定部分

 #include  #include  #include  #include  #include  #include  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; } 

这按预期工作。 连接到127.0.0.1自己尝试一下。 如果主机上没有运行服务器,则它将无法连接(连接将返回-1并且将正确设置errno)。

确保用于连接的IP地址确实指向您的服务器。

recv中还有一个问题:

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

变量message是一个未分配给任何内存的指针(它包含一些堆栈垃圾值),并且您正在覆盖它。 参见recv(2)的手册 。

要修复此问题,您应该将指针指定给一些已分配的内存:

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

或使用堆栈而不是堆来存储消息字节:

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

我假设你的消息总是一个字节。

请记住,在这里:

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

您正在打印返回代码而不是实际消息。