免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 9767 | 回复: 20
打印 上一主题 下一主题

[C] 请教有关localsocket的问题 android与linux程序本地通信 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-06-16 21:28 |只看该作者 |倒序浏览
本帖最后由 sithui 于 2014-06-16 22:35 编辑

一个android程序需要与linux的守护进程进行通信,打算采用localsocket的方式,试验中发现linux的收发程序可以正常工作,android程序之间也可以正常工作,但linux与android相互不能通信。
发现一个问题,localsocket中要用到一个文件来发送,android把通信文件放在/data/data/目录下,linux程序放在当前的运行目录下。
不知道还有没有别的问题,有谁做过的帮我讲讲怎么回事。

client

  1. #include <stdio.h>
  2. #include <stddef.h>
  3. #include <sys/stat.h>
  4. #include <sys/socket.h>
  5. #include <sys/un.h>
  6. #include <errno.h>
  7. #include <string.h>

  8. /* Create a client endpoint and connect to a server.   Returns fd if all OK, <0 on error. */
  9. int unix_socket_conn(const char *servername)
  10. {
  11.     int fd;
  12.     if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)    /* create a UNIX domain stream socket */
  13.     {
  14.         return(-1);
  15.     }
  16.     int len, rval;
  17.     struct sockaddr_un un;         
  18.     memset(&un, 0, sizeof(un));            /* fill socket address structure with our address */
  19.     un.sun_family = AF_UNIX;
  20.     sprintf(un.sun_path, "scktmp%05d", getpid());
  21.     len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
  22.     unlink(un.sun_path);               /* in case it already exists */
  23.     if (bind(fd, (struct sockaddr *)&un, len) < 0)
  24.     {
  25.         rval=  -2;
  26.     }
  27.     else
  28.     {
  29.         /* fill socket address structure with server's address */
  30.         memset(&un, 0, sizeof(un));
  31.         un.sun_family = AF_UNIX;
  32.         strcpy(un.sun_path, servername);
  33.         len = offsetof(struct sockaddr_un, sun_path) + strlen(servername);
  34.         if (connect(fd, (struct sockaddr *)&un, len) < 0)
  35.         {
  36.             rval= -4;
  37.         }
  38.         else
  39.         {
  40.             return (fd);
  41.         }
  42.     }
  43.     int err;
  44.     err = errno;
  45.     close(fd);
  46.     errno = err;
  47.     return rval;          
  48. }

  49. void unix_socket_close(int fd)
  50. {
  51.     close(fd);     
  52. }


  53. int main(void)
  54. {
  55.     srand((int)time(0));
  56.     int connfd;
  57.     connfd = unix_socket_conn("foo.sock");
  58.     if(connfd<0)
  59.     {
  60.         printf("Error[%d] when connecting...",errno);
  61.         return 0;
  62.     }
  63.     printf("Begin to recv/send...\n");  
  64.     int i,n,size;
  65.     char rvbuf[4096];
  66.     for(i=0;i<10;i++)
  67.     {
  68.         /*
  69.         //=========接收=====================
  70.         size = recv(connfd, rvbuf, 800, 0);   //MSG_DONTWAIT
  71.         if(size>=0)
  72.         {
  73.         printf("Recieved Data[%d]:%c...%c\n",size,rvbuf[0],rvbuf[size-1]);
  74.         }
  75.         if(size==-1)
  76.         {
  77.         printf("Error[%d] when recieving Data.\n",errno);         
  78.         break;               
  79.         }
  80.         if(size < 800) break;
  81.         */
  82.         //=========发送======================
  83.         memset(rvbuf,'a',2048);
  84.         rvbuf[2047]='b';
  85.         size = send(connfd, rvbuf, 2048, 0);
  86.         if(size>=0)
  87.         {
  88.             printf("Data[%d] Sended:%c.\n",size,rvbuf[0]);
  89.         }
  90.         if(size==-1)
  91.         {
  92.             printf("Error[%d] when Sending Data:%s.\n",errno,strerror(errno));         
  93.             break;               
  94.         }
  95.         sleep(1);
  96.     }
  97.     unix_socket_close(connfd);
  98.     printf("Client exited.\n");   
  99. }
复制代码
server

  1. #include <stdio.h>
  2. #include <sys/stat.h>
  3. #include <sys/socket.h>
  4. #include <sys/un.h>
  5. #include <errno.h>
  6. #include <stddef.h>
  7. #include <string.h>

  8. // the max connection number of the server
  9. #define MAX_CONNECTION_NUMBER 5

  10. /* * Create a server endpoint of a connection. * Returns fd if all OK, <0 on error. */
  11. int unix_socket_listen(const char *servername)
  12. {
  13.     int fd;
  14.     struct sockaddr_un un;
  15.     if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
  16.     {
  17.         return(-1);
  18.     }
  19.     int len, rval;
  20.     unlink(servername);               /* in case it already exists */
  21.     memset(&un, 0, sizeof(un));
  22.     un.sun_family = AF_UNIX;
  23.     strcpy(un.sun_path, servername);
  24.     len = offsetof(struct sockaddr_un, sun_path) + strlen(servername);
  25.     /* bind the name to the descriptor */
  26.     if (bind(fd, (struct sockaddr *)&un, len) < 0)
  27.     {
  28.         rval = -2;
  29.     }
  30.     else
  31.     {
  32.         if (listen(fd, MAX_CONNECTION_NUMBER) < 0)   
  33.         {
  34.             rval =  -3;
  35.         }
  36.         else
  37.         {
  38.             return fd;
  39.         }
  40.     }
  41.     int err;
  42.     err = errno;
  43.     close(fd);
  44.     errno = err;
  45.     return rval;       
  46. }

  47. int unix_socket_accept(int listenfd, uid_t *uidptr)
  48. {
  49.     int clifd, len, rval;
  50.     time_t staletime;
  51.     struct sockaddr_un un;
  52.     struct stat statbuf;
  53.     len = sizeof(un);
  54.     if ((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < 0)
  55.     {
  56.         return(-1);     
  57.     }
  58.     /* obtain the client's uid from its calling address */
  59.     len -= offsetof(struct sockaddr_un, sun_path);  /* len of pathname */
  60.     un.sun_path[len] = 0; /* null terminate */
  61.     if (stat(un.sun_path, &statbuf) < 0)
  62.     {
  63.         rval = -2;
  64.     }
  65.     else
  66.     {
  67.         if (S_ISSOCK(statbuf.st_mode) )
  68.         {
  69.             if (uidptr != NULL) *uidptr = statbuf.st_uid;    /* return uid of caller */
  70.             unlink(un.sun_path);       /* we're done with pathname now */
  71.             return clifd;                 
  72.         }
  73.         else
  74.         {
  75.             rval = -3;     /* not a socket */
  76.         }
  77.     }
  78.     int err;
  79.     err = errno;
  80.     close(clifd);
  81.     errno = err;
  82.     return(rval);
  83. }

  84. void unix_socket_close(int fd)
  85. {
  86.     close(fd);     
  87. }

  88. int main(void)
  89. {
  90.     int listenfd,connfd;
  91.     listenfd = unix_socket_listen("foo.sock");
  92.     if(listenfd<0)
  93.     {
  94.         printf("Error[%d] when listening...\n",errno);
  95.         return 0;
  96.     }
  97.     printf("Finished listening...\n",errno);
  98.     uid_t uid;
  99.     connfd = unix_socket_accept(listenfd, &uid);
  100.     unix_socket_close(listenfd);  
  101.     if(connfd<0)
  102.     {
  103.         printf("Error[%d] when accepting...\n",errno);
  104.         return 0;
  105.     }  
  106.     printf("Begin to recv/send...\n");  
  107.     int i,n,size;
  108.     char rvbuf[2048];
  109.     for(i=0;i<200;i++)
  110.     {
  111.         //===========接收==============
  112.         memset(rvbuf, 0x00, sizeof(rvbuf));
  113.         size = recv(connfd, rvbuf, 2048, 0);   
  114.         if(size>=0)
  115.         {
  116.             // rvbuf[size]='\0';
  117.             printf("Recieved Data[%d]:%c...%c\n",size,rvbuf[0],rvbuf[size-1]);
  118.         }
  119.         if(size==-1)
  120.         {
  121.             printf("Error[%d] when recieving Data:%s.\n",errno,strerror(errno));         
  122.             break;               
  123.         }
  124.         /*
  125.         //===========发送==============
  126.         memset(rvbuf, 'c', 2048);
  127.         size = send(connfd, rvbuf, 2048, 0);
  128.         if(size>=0)
  129.         {
  130.         printf("Data[%d] Sended.\n",size);
  131.         }
  132.         if(size==-1)
  133.         {
  134.         printf("Error[%d] when Sending Data.\n",errno);         
  135.         break;               
  136.         }
  137.         */
  138.         sleep(1);
  139.     }
  140.     unix_socket_close(connfd);
  141.     printf("Server exited.\n");   
  142. }
复制代码

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
2 [报告]
发表于 2014-06-16 21:58 |只看该作者
啥叫“localsocket”?

论坛徽章:
0
3 [报告]
发表于 2014-06-16 22:38 |只看该作者
回复 2# windoze
其实socket一样的。。。。

刚刚又试了,client和server之间如果不是在同一目录下也不能通信


   

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
4 [报告]
发表于 2014-06-16 22:52 |只看该作者
回复 3# sithui

我的意思是说,Unix下没有一个叫“localsocket”的东西。
你用的要么是Unix Domain Socket,要么是TCP loopback socket,总之你要说清楚。
如果是TCP loopback socket,不通就是你程序写错了;如果是Unix domain socket,你要看看对应的文件是不是两边的进程都有正确的权限,否则肯定通不了。

论坛徽章:
0
5 [报告]
发表于 2014-06-16 23:00 |只看该作者
回复 4# windoze


    看到我贴的代码没,foo.sock这个文件就是了,如果不是同一目录下执行server和client就会有问题。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
6 [报告]
发表于 2014-06-16 23:03 |只看该作者
回复 5# sithui

你的代码我没看,犯懒。
话说你有没有检查你这个foo.sock文件的权限?

论坛徽章:
0
7 [报告]
发表于 2014-06-16 23:07 |只看该作者
本帖最后由 sithui 于 2014-06-16 23:11 编辑

回复 6# windoze
文件权限是

    srwxrwxrwx root     root
其实我是在嵌入式系统中做的,放到PC上也试了下,一样的问题。权限是用户权限,而不是root:
   srwxrwxr-x 1 carlton carlton

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
8 [报告]
发表于 2014-06-16 23:22 |只看该作者
你改用TCP Loopback socket试试?

论坛徽章:
0
9 [报告]
发表于 2014-06-17 00:14 |只看该作者
回复 8# windoze


    loopback肯定不会有问题的。
以前没有用过unix domain sock

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
10 [报告]
发表于 2014-06-17 08:32 |只看该作者
回复 9# sithui

晕死,刚看了一眼你的程序,你难道没发现你没用绝对路径么?两个程序打开的不是同一个foo.sock当然连不上了……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP