unix socket实现进程通信

抄一段使用unix socket client的c代码

#include <stdio.h>  
#include <stddef.h>  
#include <sys/stat.h>  
#include <sys/socket.h>
#include <sys/un.h>  
#include <errno.h>  
#include <string.h>  
  
/* Create a client endpoint and connect to a server.   Returns fd if all OK, <0 on error. */  
int unix_socket_conn(const char *servername)  
{   
  int fd;   
  if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)    /* create a UNIX domain stream socket */   
  {  
    return(-1);  
  }  
  int len, rval;  
   struct sockaddr_un un;            
  memset(&un, 0, sizeof(un));            /* fill socket address structure with our address */  
  un.sun_family = AF_UNIX;   
  sprintf(un.sun_path, "scktmp%05d", getpid());   
  len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);  
  unlink(un.sun_path);               /* in case it already exists */   
  if (bind(fd, (struct sockaddr *)&un, len) < 0)  
  {   
     rval=  -2;   
  }   
  else  
  {  
    /* fill socket address structure with server's address */  
      memset(&un, 0, sizeof(un));   
      un.sun_family = AF_UNIX;   
      strcpy(un.sun_path, servername);   
      len = offsetof(struct sockaddr_un, sun_path) + strlen(servername);   
      if (connect(fd, (struct sockaddr *)&un, len) < 0)   
      {  
          rval= -4;   
      }   
      else  
      {  
         return (fd);  
      }  
  }  
  int err;  
  err = errno;  
  close(fd);   
  errno = err;  
  return rval;      
}  
   
 void unix_socket_close(int fd)  
 {  
    close(fd);       
 }  
  
  
int main(void)  
{   
  srand((int)time(0));  
  int connfd;   
  connfd = unix_socket_conn("foo.sock");  
  if(connfd<0)  
  {  
     printf("Error[%d] when connecting...",errno);  
     return 0;  
  }  
   printf("Begin to recv/send...\n");    
  int i,n,size;  
  char rvbuf[4096];  
  for(i=0;i<10;i++)  
  {  
/* 
    //=========接收===================== 
    size = recv(connfd, rvbuf, 800, 0);   //MSG_DONTWAIT 
     if(size>=0) 
     { 
        printf("Recieved Data[%d]:%c...%c\n",size,rvbuf[0],rvbuf[size-1]); 
     } 
     if(size==-1) 
     { 
         printf("Error[%d] when recieving Data.\n",errno);    
             break;      
     } 
         if(size < 800) break; 
*/  
    //=========发送======================  
memset(rvbuf,'a',2048);  
         rvbuf[2047]='b';  
         size = send(connfd, rvbuf, 2048, 0);  
     if(size>=0)  
     {  
        printf("Data[%d] Sended:%c.\n",size,rvbuf[0]);  
     }  
     if(size==-1)  
     {  
        printf("Error[%d] when Sending Data:%s.\n",errno,strerror(errno));     
            break;        
     }  
         sleep(1);  
  }  
   unix_socket_close(connfd);  
   printf("Client exited.\n");      
 }  

要运行在Android平台上的话,要生成可执行文件,下了cygwin和mingw都没搞定。查了查发现ndk完全可以解决:就只需要在Android.mk最后的BUILD模式改成BUILD_EXECUTABLE就好,生成so文件的话模式是BUILD_SHARED_LIBRARY。
touch一个foo.sock文件,然后先运行Server端,再运行Client则可以发送成功!

java端

https://github.com/mcfunley/juds
https://github.com/jnr/jnr-unixsocket
https://github.com/kohlschutter/junixsocket

java需要使用第三方库才能使用unix socket,这里我们使用的是第一个mcfunley/juds,因为它star竟高出第二名15个!!!嗯。
unix socket分两种类型,一种类似TCP,叫做STREAM类型,一种类似UDP,叫做DGRAM类型。按自己的理解调用一下:

try {
            boolean result = new File("/mnt/sdcard/uds").createNewFile();
            Log.d(TAG, "create file result=" + result);
            final UnixDomainSocketClient streamClient = new UnixDomainSocketClient("/mnt/sdcard/uds", JUDS.SOCK_STREAM);
            final UnixDomainSocketServer streamServer = new UnixDomainSocketServer("/mnt/sdcard/uds", JUDS.SOCK_STREAM);

            new Thread(){
                @Override
                public void run() {
                    byte[] buf = new byte[128];
                    try {
                        int count = streamServer.getInputStream().read(buf);
                        Log.d(TAG, "size of data=" + count);
                        for(byte b : buf){
                            Log.d(TAG, "byte=" + b);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();

            new Thread(){
                @Override
                public void run() {
                    try {
                        streamClient.getOutputStream().write("Hello stm".getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();

        } catch (IOException e) {
            e.printStackTrace();
        }

2017-5-19
java端与c端的通信报出java.io.IOException: Unable to write to Unix domain socket
问题有待解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值