socket IPC与一般网络通信一致,也有两种类型sock_stream 和sock_daram不同的地方在于:
1.网络通信server端以IP/Port作为服务名,IPC则以socket文件路径名作为服务名,socket文件与一般文件不同,socket文件是在程序运行时创建,而不能手动创建。
2.Domain不同,一个是AF_INET,一个是AF_UNIX;使用的地址结构不同,一个是sockaddr_in,一个是sockaddr_un. struct sockaddr_un{int sun_family;char sun_path[108];}
3.客户端与服务器一样可以绑定一个文件路径,绑定之后会生成一个socket文件。此文件并没有什么作用,可以直接删除,通信不会受到影响。
//server端
#include <stdio.h>
#include <stdlib.h>#include <sys/socket.h>
#include <sys/un.h>
#include <stddef.h>
#include <unistd.h>
int bindSocket(char* servname)
{
struct sockaddr_un usock;
int ufd;
memset(&usock,0,sizeof(sockaddr_un));
usock.sun_family = AF_UNIX;
strcpy(usock.sun_path,servname);
if((ufd = socket(AF_UNIX,SOCK_STREAM,0)) < 0)
{
perror("socket() error!");
exit(-1);
}
int len = offsetof(sockaddr_un,sun_path) + strlen(usock.sun_path);
if(bind(ufd,(sockaddr*)&usock,len) < 0)
{
perror("bind() error!");
exit(-1);
}
return ufd;
}
int acceptSocket(int ssock,sockaddr_un *un)
{
int csock,len;
len = sizeof(un); //这句话必须有,因为len是传入传出参数,在传入时如果没有指定大小,有可能传入上次传出参数值。
{
perror("accept() error!");
exit(-1);
}
len -= offsetof(sockaddr_un,sun_path);
un->sun_path[len] = 0;
printf("client file:%s\n",un->sun_path);
return csock;
}
int main(void)
{
char servName[20];
sprintf(servName,"server");
int sfd = bindSocket(servName);
if(listen(sfd,5) < 0)
{
perror("listen() error!");
exit(-1);
}
struct sockaddr_un un;
int cfd = acceptSocket(sfd,&un);
char buf[100];
int s = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,s);
}
//客户端
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/un.h>
#include <stddef.h>
int cli_connect(const char *name)
{
int len;
struct sockaddr_un un;
memset(&un,0,sizeof(un));
un.sun_family = AF_UNIX;
sprintf(un.sun_path,"client%05d",getpid());
int cfd;
if((cfd = socket(AF_UNIX,SOCK_STREAM,0)) < 0)
{
perror("socket() error");
exit(-1);
}
len = offsetof(sockaddr_un,sun_path) + strlen(un.sun_path);
if(bind(cfd,(sockaddr*)&un,len) < 0)
{
perror("bind() error");
exit(-1);
}
memset(&un,0,sizeof(un));
un.sun_family = AF_UNIX;
sprintf(un.sun_path,name);
len = offsetof(sockaddr_un,sun_path);
len += strlen(un.sun_path);
printf("%s\n",un.sun_path);
if(connect(cfd,(sockaddr*)&un,len) < 0)
{
perror("connect() error");
exit(-1);
}
return cfd;
}
int main(void)
{
int cfd = cli_connect("qw/server");
char *buf = "hello world!";
if(write(cfd,buf,strlen(buf)) < 0)
perror("error");
return cfd;
}