Проблемы с сетью Android NDK: сбой соединения TCP - PullRequest
6 голосов
/ 08 февраля 2011

У меня проблемы с Android NDK.

Для моего проекта требуются программные компоненты, написанные на C, которые могут получать данные по TCP для выполнения в ОС Android.

С этой целью я создал простой сервер и клиент на C, используя сокеты BSD, и могу успешно отправлять сообщения туда и обратно через соединение на ПК. Теперь я переместил клиентский код в NDK и не могу подключиться к своему серверу с эмулятора или с реального устройства Android. NDK компилируется без предупреждений или ошибок, эмулятор / телефон подключены к Wi-Fi и имеют разрешения на доступ к Интернету в манифесте. Что дает?

Все, что он делает - это создает сокет, заполняет информацию о хосте / порте и пытается подключиться: если он подключается, отправьте сообщение, иначе верните ошибку. Android всегда возвращает отрицательное значение для подключения


Этот клиентский код, скомпилированный / выполненный на Mac / Windows / Linux, работает:

ПК-код клиента:

int tcp_socket = socket(AF_INET, SOCK_STREAM,0); 
if(tcp_socket< 0 ) {
    cerr << "Failed to create TCP socket." << endl;
    return 2;
}

sockaddr_in server_tcp_add;
server_tcp_add.sin_family = AF_INET;
server_tcp_add.sin_port = htons(tcp_port); //set via command line: Yes, they are the same for the android
hostent *hostp = gethostbyname(server_host);
memcpy(&server_tcp_add.sin_addr, hostp->h_addr, hostp->h_length); 
socklen_t slen = sizeof(server_tcp_add);

if(connect(tcp_socket,(sockaddr*)&server_tcp_add, slen) <0 ){
    cerr<< "Failed to connect to server with TCP. " << endl;
    close(tcp_socket);
    return 3;
}

char* myString = "This is my message";
send(tcp_socket, myString, strlen(myString), 0);

close(tcp_socket);

Этот код, выполненный на Android NDK, не

Код: Клиент NDK

jstring Java_networking_client_activate_initiateTcpConnection(JNIEnv* env, jobject javaThis){
    int tcp_socket = socket(AF_INET, SOCK_STREAM,0);
    if(tcp_socket < 0){
        return (*env)->NewStringUTF(env, "ERROR CREATING SOCKET");
    }
    const char* server_host = "some.numbers.that.work"; //It's a valid IP I don't feel like sharing
    unsigned short server_port = 43000;

    struct sockaddr_in server_tcp_addr;
    server_tcp_addr.sin_family = AF_INET;
    server_tcp_addr.sin_port = htons(server_port);
    struct hostent *hostp = gethostbyname(server_host);
    memcpy(&server_tcp_addr, hostp->h_addr, hostp->h_length);
    socklen_t slen = sizeof(server_tcp_addr);
    if(connect(tcp_socket,(struct sockaddr*)&server_tcp_addr, slen) < 0){ //fails here
        close(tcp_socket);
        return (*env)->NewStringUTF(env, "ERROR CONNECTING TO SERVER");
    }

    char* message = "hello from android!";
    send(tcp_socket, &message, sizeof(message),0);

    return (*env)->NewStringUTF(env, "TCP message sent!");
}

Во многом идентичны; для компиляции NDK требуется поместить struct перед всем.

- редактировать - я должен также упомянуть, я смог отправить данные через сокеты в Java с этим приложением. Только С-розетки, которые действительно портят дело. Даже образец кого-то, у кого C-сокеты работают через NDK, был бы очень признателен.

1 Ответ

12 голосов
/ 07 октября 2011

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

Я изменил эту строку:

memcpy(&server_tcp_addr, hostp->h_addr, hostp->h_length);

на эту:

memcpy(&server_tcp_addr.sin_addr.s_addr, hostp->h_addr, hostp->h_length);

и это помогло мне.

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