Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9996
  • 博文数量: 4
  • 博客积分: 170
  • 博客等级: 入伍新兵
  • 技术积分: 50
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-12 20:05
文章分类
文章存档

2008年(4)

我的朋友
最近访客

分类: LINUX

2008-11-17 16:24:19

                     用socket实现本地进程间的通信
    用socket实现本地进程间的通信用到unix域协议.unix域协议不是用ip和端口来标示地址,而是用普通的系统文件来表示的.除了这个不同以外,它的实现跟socket基本一样.
    unix域的套接字地址结构如下:
    struct sockaddr_un
    {
      sa_family_t sun_family;
      char        sun_path[104];//存放在这结构中的地址必须以空字符结尾.
    }
    例子:
    服务器端:
#include
#include
#include
#include
#define filename "/home/temp.unix"
int main()
{
  int s;
  int client_s;
  struct sockaddr_un  addr;
  struct sockaddr_un  client_addr;
  int len=sizeof(client_addr);
  char buff[100];
  char client_buff[100]="data from  service\n";
  int n;
                                                                                                                                              
  s=socket(AF_UNIX,SOCK_STREAM,0);
  if(s<0)
       {
               printf("create socket fail\n");
               exit(0);
       }
  unlink(filename);      //先删除文件filename,以防止它已经存在
  bzero(&addr,sizeof(addr));//这个可以保证sun_path末尾是空字符,当然前提
                            // 是保证filename字符数小于104
  addr.sun_family=AF_UNIX;
  strcpy(addr.sun_path,filename);
  if(-1==bind(s,(struct sockaddr *)&addr,sizeof(addr)))
       {
               printf("bind socket fail\n");
               exit(0);
       }
  chmod(filename,0777);
  if(-1==listen(s,5))
       {
               printf("create listen socket fail!\n");
               exit(0);
       }
  client_s=accept(s,(struct sockaddr *)&client_addr,&len);
                                                                                                                                              
  n=read(client_s,buff,sizeof(buff)-1);
  buff[n]='\0';
  printf("data=%s\n",buff);
  write(client_s,client_buff,sizeof(client_buff));
  close(client_s);
  close(s);
  unlink(filename);  //最后把它删除
  return 1;
                                                                                                                                              
}
 
客户端:
 #include
 #include
 #include
 #include
 #include
#define filename "/home/temp.unix"
 int main()
 {
   int s;
   int client_s;
   struct sockaddr_un  addr;
   char buff[100];
   char ser_buff[100]="data from client\n";
   int n;
   s=socket(AF_UNIX,SOCK_STREAM,0);
   if(s<0)
       {
             printf("create socket fail\n");
             exit(0);
        }
 bzero(&addr,sizeof(addr));
 addr.sun_family=AF_UNIX;
 strcpy(addr.sun_path,filename);
 if(-1==connect(s,(struct sockaddr *)&addr,sizeof(addr)))
                                  {
                     printf("connect socket fail and the errno=%d\n",errno);
                     exit(0);
                                  }
 write(s,ser_buff,sizeof(ser_buff));
 n=read(s,buff,sizeof(buff)-1);
 buff[n]='\0';
 printf("from service data=%s\n");
 close(s);
 return 1;
 }

 注意点:
 1:文件名应该用绝对路径,而不应该是相对路径.因为服务器和客户端都要用到这文件.如果用相对路径的话,
   那就要保证服务器和客户端要放在同个目录下,否则后果不可预料.
 2:用bind创建的文件属性默认是0777.但是它创建完后就会按照当前的umask值进行修改.
 3:客户端调用connect时要保证unix套接字已经存在,否则会发生错误,errno=2(没有这文件和目录).
 4:如果用的是数据报的协议,那么客户端要显示绑定一个路径名,这样服务器才会知道回复的地址.这主要
   是因为unix域不会默认产生一个路径名与socket绑定.
阅读(1918) | 评论(0) | 转发(1) |
0

上一篇:信号

下一篇:进程间传送句柄

给主人留下些什么吧!~~