【问题标题】:Android NDK Networking problems: TCP Connection failsAndroid NDK 网络问题:TCP 连接失败
【发布时间】:2011-06-23 01:52:03
【问题描述】:

我在使用 Android NDK 时遇到了一些问题。

我的项目需要用 C 语言编写的可以通过 TCP 接收数据的软件组件,以便在 Android 操作系统上执行。

为此,我使用 BSD 套接字用 C 语言制作了一个简单的服务器和客户端,并且可以通过 PC 上的连接成功地来回发送消息。现在我已经将客户端代码移动到 NDK 中,并且无法从模拟器或实际的 android 设备连接到我的服务器。 NDK 编译时没有警告或错误,模拟器/手机在 wifi 上,并且在清单中启用了互联网权限。是什么赋予了?

它所做的只是创建一个套接字,填写主机/端口信息并尝试连接:如果确实连接,则发送消息,否则返回错误。 Android 总是为连接返回负值


这个客户端代码,在 Mac/Windows/Linux 上编译/执行,可以工作:

PC 客户端代码:

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!");
}

大体相同;需要将 struct 放在所有内容前面以便 NDK 编译。

--edit--我还应该提到,我已经能够使用这个应用程序在 Java 中通过套接字发送数据。只是真正搞砸的C插座。即使是具有通过 NDK 工作的 C 套接字的其他人的示例也将不胜感激。

【问题讨论】:

  • 两个想法:首先看看您是否可以从 adb 命令行使用 Web 浏览器或 netcat (nc) 之类的其他东西,甚至可以 ping 来验证您是否可以访问主机。其次,检查您是否为所有结构使用了正确的长度值,有一个(不记得是哪个)人们经常会错误地认为它可以在某些实现上工作而在其他实现上不起作用。
  • connect() 失败时能检查errno吗?
  • 把这个问题放了几天,又回来了。回复 cmets:我可以使用我现在正在测试的 Droid 手机上的浏览器。我也很确定这些是正确的 len 函数。我已经像__android_log_write(ANDROID_LOG_ERROR,"socket errno", strerror(errno)); 一样从NDK 访问了errno,并且打印的错误是“协议不支持地址系列”。一直在谷歌搜索答案,认为这可能与 ipv6/4 问题或手机上的主机文件有关。非常感谢任何进一步的帮助

标签: android sockets networking tcp android-ndk


【解决方案1】:

这是一个很晚的答案,但它可能仍然有用......

我改变了这一行:

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

到这里:

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

这对我有用。

【讨论】:

    猜你喜欢
    • 2020-06-14
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多