2012-06-22 2 views
2

En fait, je fais un test avec le server.c et client.c dans l'émulateur android (ps: ils fonctionnent tous les deux avec succès et sont compilés avec le compilateur croisé android générique) .Et , alors je vais plus loin, je réécris le côté client via le jni. Mais, dans ce cas, le client ne parvient pas à se connecter au côté serveur, bien que le nouveau client soit très similaire au client.c. Après la recherche, quelqu'un mentionne que la permission compte.Mais, quand j'ajoute le <uses-permission android:name="android.permission.INTERNET" /> (ps: ces balises sont en dehors des balises de l'application), le problème persiste. Et comme le montre le logcat, le code java inactive réellement la méthode c, mais, pourquoi pas, il se comporte comme le client.c? Toute idée me profitera beaucoup. Merci d'avance!erreur de connexion de la programmation socket via ndk

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

code Java: paquet gz.kaiwii;

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

code natif:

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

le logcat: enter image description here

+0

Je l'ai édité avec le logcat.thx! –

+0

Le serveur écoute-t-il? Que diriez-vous d'imprimer le message d'erreur sur l'échec de connexion? Utilisez errno et strerror pour cela. –

+0

@ Mārtiņš Možeiko, le serveur invite l'erreur, Pas de tel fichier ou répertoire.Et le client invite connexion refusée.Mais, si je n'utilise pas le jni pour appeler le code natif, tout fonctionne bien. –

Répondre

0

Si j'utilise l'espace abstrait comme le nom, tout fonctionne okay.But, une chose devrait être mis en garde est la longueur !

+0

votre question m'a été très utile. Pouvez-vous s'il vous plaît dire si nous pouvons avoir à la fois le serveur et le client dans le jni lui-même ??? Si oui, comment démarrer le serveur et le client en même temps pour envoyer et recevoir les données respectivement ... – Zax