Android localSocket连接拒绝〜

时间:2017-04-16 13:44:15

标签: android localsocket

我最近通过localsocket写了一个框架和应用程序之间的通信示例,本机服务器套接字代码:

#include "base.h"
#include "util.h"




 namespace yanghui{
    JavaVM* getJavaVm();
    Constants* getConstants();
    };

    using namespace yanghui;

    namespace localsocket{

    #define MAX_BUFFER_SIZE 80

    /**
     * create a local unix socket.
     */
     int NewLocalSocket(JNIEnv* env,jobject obj){

    LOGD("Constructing a new Local UNIX socket...");
    int localSocket = socket(PF_LOCAL,SOCK_STREAM,0);
    if( -1 == localSocket){
        getConstants()->throwJavaException(env,"java/io/IOException",errno);
    }
    return localSocket;

}


/**
* binding socket.
*/

void BindLocalSocketToName(JNIEnv* env,jobject obj,int sd,const char* name){

    struct sockaddr_un address;

    const size_t nameLength = strlen(name);
    size_t pathLength = nameLength;

    bool abstractNamespace = ('/' != name[0]);
    if(abstractNamespace){
        pathLength++;
    }

    if(pathLength > sizeof(address.sun_path)){
        getConstants()->throwJavaException(env,"java/io/IOException",errno);
    }else{
        memset(&address,0,sizeof(address));
        address.sun_family = PF_LOCAL;

        char* sunPath = address.sun_path;

        //If namespace is abstract,the first byte is 0.
        if(abstractNamespace){
            *sunPath++ = NULL;
        }

         //append name.
         strcpy(sunPath,name);

         //Address length.   
         socklen_t addressLength = (offsetof(struct sockaddr_un,sun_path))
            + pathLength;

         unlink(address.sun_path);

         LOGD("Binding to local name %s%s.",(abstractNamespace)?"null":"",name);
         bind(sd,(struct sockaddr*)&address,addressLength);
         /*
         if(-1 == bind(sd,(struct sockaddr*)&address,addressLength)){
             getConstants()->throwJavaException(env,"java/io/IOException","Binding socket error ~");
         }
         */
    }
}


/**
*  waiting for socket.
*/


int AcceptOnLocalSocket(JNIEnv* env,jobject obj,int sd){
    LOGD("Waiting for a client connection...");
    int clientSocket = accept(sd,NULL,NULL);

    LOGD("sd = %d ",sd);
    if(-1 == clientSocket){
        getConstants()->throwJavaException(env,"java/io/IOException",errno);
    }
    return clientSocket;
}


/**
* Listening coming in socketclient.
*/


void ListenOnSocket(JNIEnv* env,jobject obj,int sd,int backlog){
    LOGD("Listening on socket with a backlog of %d pending connections.",backlog);

    listen(sd,backlog);
    /*
    if( -1 == listen(sd,backlog)){
        getConstants()->throwJavaException(env,"java/io/IOException",errno);
    }
    */


}

/**
* Receive buffer from localsocket.
*/


ssize_t ReceiveFromSocket(JNIEnv* env,jobject obj,int sd,char* buffer,size_t bufferSize){
    LOGD("Receiving from the socket...");
    ssize_t recvSize = recv(sd,buffer,bufferSize-1,0);

    if(-1 == recvSize){
      getConstants()->throwJavaException(env,"java/io/IOException",errno);
    }else{
        buffer[recvSize] = NULL;
        if(recvSize > 0){
            LOGD("Received %d bytes : %s",recvSize,buffer);
        }else{
            LOGD("Client disconnected.");
        }
    }
    return recvSize;
}

/**
* send buffer to socket.
*/


ssize_t SendToSocket(JNIEnv* env,jobject obj,int sd,const char* buffer,size_t bufferSize){
    LOGD("Sending to the socket...");
    ssize_t sentSize = send(sd,buffer,bufferSize,0);

    if(-1 == sentSize){
          getConstants()->throwJavaException(env,"java/io/IOException",errno);
    }else{
        if(sentSize > 0){
            LOGD("Sent %d bytes : %s",sentSize,buffer);
        }else{
            LOGD("Client disconnected.");
        }
    }
    return sentSize;
}


/**
* start Localsocket server
*/


void com_jni_nativeStartLocalServer(JNIEnv* env,jobject obj,jstring name){

    int serverSocket = NewLocalSocket(env,obj);
    if(NULL == env->ExceptionOccurred()){
        const char* nameText = env->GetStringUTFChars(name,NULL);
        if(NULL == nameText)
            goto exit;

        BindLocalSocketToName(env,obj,serverSocket,nameText);

        env->ReleaseStringUTFChars(name,nameText);

        if(NULL != env->ExceptionOccurred()){
            LOGD("binding error");
            goto exit;
        }

        ListenOnSocket(env,obj,serverSocket,4);
        if(NULL != env->ExceptionOccurred()){
             LOGD("listen error");
             goto exit;
        }

        int clientSocket = AcceptOnLocalSocket(env,obj,serverSocket);
        if(NULL != env->ExceptionOccurred()){
            LOGD("acceptOnLocalSocket error.");
            goto exit;
        }


        char buffer[MAX_BUFFER_SIZE];
        ssize_t recvSize;
        ssize_t sentSize;

        while(1){
            recvSize = ReceiveFromSocket(env,obj,clientSocket,buffer,MAX_BUFFER_SIZE);

            if((0 == recvSize) || (NULL != env->ExceptionOccurred()))
                break;

            sentSize = SendToSocket(env,obj,clientSocket,buffer,(size_t)recvSize);

            if((0 == sentSize) || (NULL != env->ExceptionOccurred()))
                break;
        }

        close(clientSocket);
    }

    exit:
         if(serverSocket > 0){
             close(serverSocket);
         }
    }

};

客户端套接字:

 /**
 * filp local socket commuication activity
 * @param view
 */
public void LocalSocket(View view){
    final  String socketName = "/data/data/com.example.administrator.helloworld/files/file";
    final String message = "test";

    ServerTask serverTask = new ServerTask(socketName);
    serverTask.start();

    mHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            ClientTask clientTask = new ClientTask(socketName,message);
            clientTask.start();
        }
    },3000);


}


 /**
 * Server Task
 */
private class ServerTask extends Thread{

    private final String serverName;

    public ServerTask(String name){
        serverName = name;
    }

    @Override
    public void run() {
        Log.d("ServerTask","Starting server .");
        try{
            ndktest.nativeStartLocalServer(serverName);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

//Client Task
private class ClientTask extends Thread{

    private final String name;
    private final String message;

    public ClientTask(String name,String message){
        this.name = name;
        this.message = message;
    }

    @Override
    public void run() {
        Log.d("ClientTask","Starting client");
        try{
            startLocalClient(name,message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

  private void startLocalClient(String name,String message) throws Exception{

    //create a localsocket
    LocalSocket clientSocket = new LocalSocket();
    try{
        //setting localsocket namespace
        LocalSocketAddress.Namespace namespace = LocalSocketAddress.Namespace.FILESYSTEM;;

        LocalSocketAddress address = new LocalSocketAddress(name,namespace);

        Log.i("startLocalClient","Connecting to "+name);
        clientSocket.connect(address);
        Log.i("startLocalClient","Connected.");
        byte[] messageBytes = message.getBytes();
        Log.i("startLocalClient","Sending to the socket...");
        OutputStream outputStream = clientSocket.getOutputStream();
        outputStream.write(messageBytes);
        Log.i("startLocalClient",String.format("Sent %d bytes : %s",messageBytes.length,message));

        Log.i("startLocalClient","Receiving from the socket...");
        InputStream inputStream = clientSocket.getInputStream();
        int readSize = inputStream.read(messageBytes);

        String receivedMessage = new String(messageBytes,0,readSize);
        Log.i("startLocalClient",String.format("Received %d bytes: %s",readSize,receivedMessage));

        outputStream.close();
        inputStream.close();

    }catch (Exception e){
        e.printStackTrace();
    }finally {
        clientSocket.close();
    }
}

我使用FILESYSTEM创建localsocket,但运行logcat是:

01-01 08:24:48.504 14396-14836/com.example.administrator.helloworld D/ServerTask: Starting server .
01-01 08:24:48.505 14396-14836/com.example.administrator.helloworld D/ndklog: Constructing a new Local UNIX socket...
01-01 08:24:48.505 14396-14836/com.example.administrator.helloworld D/ndklog: Binding to local name /data/data/com.example.administrator.helloworld/files/file.
01-01 08:24:48.505 14396-14836/com.example.administrator.helloworld D/ndklog: Listening on socket with a backlog of 4 pending connections.
01-01 08:24:48.505 14396-14836/com.example.administrator.helloworld D/ndklog: Waiting for a client connection...
01-01 08:24:48.505 14396-14836/com.example.administrator.helloworld D/ndklog: sd = 42 
01-01 08:24:48.507 14396-14836/com.example.administrator.helloworld D/ndklog: acceptOnLocalSocket error.
01-01 08:24:48.507 14396-14836/com.example.administrator.helloworld W/System.err: java.io.IOException: Invalid argument
01-01 08:24:48.507 14396-14836/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.Ndktest.nativeStartLocalServer(Native Method)
01-01 08:24:48.507 14396-14836/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.MainActivity$ServerTask.run(MainActivity.java:77)
01-01 08:24:51.510 14396-14938/com.example.administrator.helloworld D/ClientTask: Starting client
01-01 08:24:51.511 14396-14938/com.example.administrator.helloworld I/startLocalClient: Connecting to /data/data/com.example.administrator.helloworld/files/file
01-01 08:24:51.512 14396-14938/com.example.administrator.helloworld W/System.err: java.io.IOException: No such file or directory
01-01 08:24:51.512 14396-14938/com.example.administrator.helloworld W/System.err:     at android.net.LocalSocketImpl.connectLocal(Native Method)
01-01 08:24:51.512 14396-14938/com.example.administrator.helloworld W/System.err:     at android.net.LocalSocketImpl.connect(LocalSocketImpl.java:290)
01-01 08:24:51.512 14396-14938/com.example.administrator.helloworld W/System.err:     at android.net.LocalSocket.connect(LocalSocket.java:130)
01-01 08:24:51.512 14396-14938/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.MainActivity.startLocalClient(MainActivity.java:118)
01-01 08:24:51.512 14396-14938/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.MainActivity.access$000(MainActivity.java:13)
01-01 08:24:51.512 14396-14938/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.MainActivity$ClientTask.run(MainActivity.java:99)

我在触摸文件下的/data/data/com./files目录中使用ADB shell,然后运行,结果是:

01-01 08:30:28.472 14396-26420/com.example.administrator.helloworld D/ServerTask: Starting server .
01-01 08:30:28.472 14396-26420/com.example.administrator.helloworld D/ndklog: Constructing a new Local UNIX socket...
01-01 08:30:28.473 14396-26420/com.example.administrator.helloworld D/ndklog: Binding to local name /data/data/com.example.administrator.helloworld/files/file.
01-01 08:30:28.474 14396-26420/com.example.administrator.helloworld D/ndklog: Listening on socket with a backlog of 4 pending connections.
01-01 08:30:28.474 14396-26420/com.example.administrator.helloworld D/ndklog: Waiting for a client connection...
01-01 08:30:28.474 14396-26420/com.example.administrator.helloworld D/ndklog: sd = 41 
01-01 08:30:28.475 14396-26420/com.example.administrator.helloworld D/ndklog: acceptOnLocalSocket error.
01-01 08:30:28.475 14396-26420/com.example.administrator.helloworld W/System.err: java.io.IOException: Invalid argument
01-01 08:30:28.475 14396-26420/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.Ndktest.nativeStartLocalServer(Native Method)
01-01 08:30:28.475 14396-26420/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.MainActivity$ServerTask.run(MainActivity.java:77)
01-01 08:30:31.465 14396-26525/com.example.administrator.helloworld D/ClientTask: Starting client
01-01 08:30:31.465 14396-26525/com.example.administrator.helloworld I/startLocalClient: Connecting to /data/data/com.example.administrator.helloworld/files/file
01-01 08:30:31.466 14396-26525/com.example.administrator.helloworld W/System.err: java.io.IOException: Connection refused
01-01 08:30:31.466 14396-26525/com.example.administrator.helloworld W/System.err:     at android.net.LocalSocketImpl.connectLocal(Native Method)
01-01 08:30:31.466 14396-26525/com.example.administrator.helloworld W/System.err:     at android.net.LocalSocketImpl.connect(LocalSocketImpl.java:290)
01-01 08:30:31.467 14396-26525/com.example.administrator.helloworld W/System.err:     at android.net.LocalSocket.connect(LocalSocket.java:130)
01-01 08:30:31.467 14396-26525/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.MainActivity.startLocalClient(MainActivity.java:118)
01-01 08:30:31.467 14396-26525/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.MainActivity.access$000(MainActivity.java:13)
01-01 08:30:31.467 14396-26525/com.example.administrator.helloworld W/System.err:     at com.example.administrator.helloworld.MainActivity$ClientTask.run(MainActivity.java:99)

我在公司使用相同代码进行通信,公司Android源码是4.4,我在家里用Android源代码6,谷歌是一个限制,我希望他们正常通信,我该如何解决它吗

0 个答案:

没有答案
相关问题