Android NDK套接字connect()在3g上应失败时返回0 [英] Android NDK socket connect() returning 0 when it should fail whilst on 3g

查看:165
本文介绍了Android NDK套接字connect()在3g上应失败时返回0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

这是客户端的代码:

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

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

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.

推荐答案

我删除了android的特定部分

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

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

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).

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

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

recv中也有问题:

Also there is a problem in recv:

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

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

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.

请记住此处:

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

您正在打印返回码,而不是实际的消息.

you are printing the return code not the actual message.

这篇关于Android NDK套接字connect()在3g上应失败时返回0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆