2012-06-22 54 views
2

其实,我已经在android模拟器(ps:它们都运行成功,并与android genric交叉编译器编译)server.c和client.c做测试。 ,然后我走得更远,我通过jni.But重写了客户端,在这种情况下,客户端无法连接到服务器端,尽管新客户端与client.c非常相似。 搜索后,有人提到权限很重要。但是,当我添加<uses-permission android:name="android.permission.INTERNET" />(ps:此标签在应用程序标签之外)时,问题仍然出现。 而随着logcat的显示,java代码实际上调用了c方法,但是,它为什么不像client.c一样呢? 任何想法都会让我受益匪浅。提前感谢!通过ndk连接套接字编程的错误

的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); 
    } 
} 

client.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(); 
} 

本地代码:

/* 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); 
} 

的logcat的: enter image description here

+0

我已经编辑它与logcat.thx! –

+0

服务器正在监听吗?如何在连接失败时打印错误消息?为此,使用errno和strerror。 –

+0

@MārtiņšMožeiko,服务器提示错误,没有这样的文件或目录,并且客户端提示连接被拒绝。但是,如果我不使用jni调用本机代码,则everyhing运行正常。 –

回答

0

如果我使用抽象名字空间的名字,一切都运行okay.But,有一点需要提醒的是长度!

+0

你的问题对我很有帮助。你能告诉我们是否可以同时拥有jni本身的服务器和客户端?如果是这样,我们如何启动服务器和客户端同时分别发送和接收数据... – Zax