Разъем Android NDK connect () возвращает 0, когда он должен потерпеть неудачу, в то время как на 3g - PullRequest
0 голосов
/ 03 июля 2018

Я написал сокет в Android NDK и сервер в c. Умеет нормально подключаться к серверу. Однако, если сервер не работает или я пытаюсь подключить его к другому случайному IP-адресу, вызов для подключения по-прежнему возвращает 0, когда он должен вернуть -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 подключено к Интернету через мобильный Интернет.

1 Ответ

0 голосов
/ 03 июля 2018

Я удалил конкретные части Android

#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. Если на хост-компьютере не запущен сервер, он не сможет подключиться (connect вернет -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);

вы печатаете код возврата, а не реальное сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...