У меня проблемы с 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, был бы очень признателен.