android - 通过ndk连接套接字编程的错误

标签 android linux android-emulator android-ndk

实际上,我已经在 android 模拟器中使用 server.c 和 client.c 进行了测试(ps:它们都运行成功并使用 android genric 交叉编译器编译)。然后我更进一步,我通过jni重写客户端。但是,在这种情况下,客户端无法连接到服务器端,尽管新客户端与client.c非常相似。 搜索后,有人提到许可很重要。但是,当我添加 <uses-permission android:name="android.permission.INTERNET" /> (ps:这个标签在application标签之外),问题依旧。 正如 logcat 所示,java 代码实际上调用了 c 方法,但是,为什么它的行为与 client.c 不同? 任何想法都会让我受益匪浅。提前致谢!

server.c:

/*  Make the necessary includes and set up the variables.  */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    int server_sockfd, client_sockfd;
    int server_len, client_len;
    struct sockaddr_un server_address;
    struct sockaddr_un client_address;

/*  Remove any old socket and create an unnamed socket for the server.  */

    unlink("server_socket");
    server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

/*  Name the socket.  */

    server_address.sun_family = AF_UNIX;
    strcpy(server_address.sun_path, "server_socket");
    server_len = sizeof(server_address);
    bind(server_sockfd, (struct sockaddr *)&server_address, server_len);

/*  Create a connection queue and wait for clients.  */

    listen(server_sockfd, 5);
    while(1) {
        char ch;

        printf("server waiting\n");

/*  Accept a connection.  */

        client_len = sizeof(client_address);
        client_sockfd = accept(server_sockfd, 
            (struct sockaddr *)&client_address, &client_len);

/*  We can now read/write to client on client_sockfd.  */

        read(client_sockfd, &ch, 1);
        ch++;
        write(client_sockfd, &ch, 1);
        close(client_sockfd);
    }
}

客户端.c:

/*  Make the necessary includes and set up the variables.  */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    int sockfd;
    int len;
    struct sockaddr_un address;
    int result;
    char ch = 'A';

/*  Create a socket for the client.  */

    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

/*  Name the socket, as agreed with the server.  */

    address.sun_family = AF_UNIX;
    strcpy(address.sun_path, "server_socket");
    len = sizeof(address);

/*  Now connect our socket to the server's socket.  */

    result = connect(sockfd, (struct sockaddr *)&address, len);

    if(result == -1) {
        perror("oops: client1");
        exit(1);
    }

/*  We can now read/write via sockfd.  */

    write(sockfd, &ch, 1);
    read(sockfd, &ch, 1);
    printf("char from server = %c\n", ch);
    close(sockfd);
    exit(0);
}

java代码: 包 gz.kaiwii;

public class NSocket {
    static{
        System.loadLibrary("NSocket");
    }
    public native void start();
}

native 代码:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>
#include <android/bitmap.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>

#define  LOG_TAG    "NSocket"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)



JNIEXPORT void JNICALL Java_gz_kaiwii_NSocket_start
  (JNIEnv * env, jobject object){
    LOGI("JNICALL Java_gz_kaiwii_NSocket_start is called!");

    int sockfd;
    int len;
    struct sockaddr_un address;
    int result;
    char ch = 'A';

/*  Create a socket for the client.  */

    LOGI(" Create a socket for the client!");

    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if(sockfd==-1){
    LOGE("create socket error!!!!!");
}

/*  Name the socket, as agreed with the server.  */

    address.sun_family = AF_UNIX;
    strcpy(address.sun_path, "server_socket");
    len = sizeof(address);

/*  Now connect our socket to the server's socket.  */

    result = connect(sockfd, (struct sockaddr *)&address, len);

    LOGI("  Now connect our socket to the server's socket.");

    if(result == -1) {
        LOGE("connect error!");
        exit(1);
    }


/*  We can now read/write via sockfd.  */

    write(sockfd, &ch, 1);
    read(sockfd, &ch, 1);
    /*
    printf("char from server = %c\n", ch);
    */
    LOGI("char from server = %c\n", ch);
    close(sockfd);
}

日志: enter image description here

最佳答案

如果我使用抽象命名空间作为名称,一切运行正常。但是,需要注意的是长度!

关于android - 通过ndk连接套接字编程的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11151945/

相关文章:

java.net.UnknownHostException 和 java.net.SocketException : Too many open files

ubuntu - Alt+Tab 后 Android 模拟器窗口保持在顶部

java - Android 按钮导航与 onclick 监听器

android - 应用程序未出现在 Android Market Place/Google Play 中

安卓用户界面设计 : Interactive ListView Elements

c++ - 在 windows 和 linux 下用 ifstream 打开二进制 .ply 文件时的不同结果

linux - 如何在 Linux 上为 Intel HD 4000 获取 OpenGL 4

android - 如何从 VS Android 模拟器连接到本地主机

android - Android Studio AVD Manager 中的 SD 卡路径更改重置

android - 无法禁用 android.widget.Button