socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率
family参数代表协议族,常用的协议族有,AF_INET、AF_INET6、AF_UNIX(或称AF_LOCAL,Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。
UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。
服务器端程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <syspes.h>
#include <string.h>
#define MAX_NUM 1024
#define UNIX_ADDR "/tmp/cc_socket"
int main()
{
int server_sockfd,client_sockfd;
int server_len,client_len;
struct sockaddr_un server_address;
struct sockaddr_un client_address;
int i,ret;
char ch_send,ch_rec;
unlink(UNIX_ADDR);
server_sockfd=socket(AF_UNIX,SOCK_STREAM,0);
if(server_sockfd==-1)
{
perror("socket");
exit(1);
}
server_address.sun_family=AF_UNIX;
strcpy(server_address.sun_path,UNIX_ADDR);
server_len=sizeof(server_address);
bind(server_sockfd,(struct sockaddr *)&server_address,server_len);
listen(server_sockfd,MAX_NUM);
printf("server waiting for client connect\n");
client_len=sizeof(client_address);
client_sockfd=accept(server_sockfd,(struct sockaddr *)&client_address,(socklen_t *)&client_len);
if(-1 != client_sockfd)
printf("the server wait for client data\n");
for(i=0,ch_send='1';i<5;i++,ch_send++)
{
if((ret=read(client_sockfd,&ch_rec,1))==-1)
{
perror("read");
exit(1);
}else
printf("the character receiver from client is:%c\n",ch_rec);
sleep(1);
if(write(client_sockfd,&ch_send,1)==-1)
{
perror("write");
exit(1);
}
}
close(client_sockfd);
unlink("UNIX_ADDR");
return 0;
}
客户端程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <syspes.h>
#include <string.h>
#define UNIX_ADDR "/tmp/cc_socket"
int main()
{
int sockfd;
int len;
struct sockaddr_un address;
int result;
int i,ret;
char ch_recv,ch_send;
sockfd=socket(AF_UNIX,SOCK_STREAM,0);
if(sockfd==-1)
{
perror("socket");
exit(1);
}
address.sun_family=AF_UNIX;
strcpy(address.sun_path,UNIX_ADDR);
len=sizeof(address);
result=connect(sockfd,(struct sockaddr*)&address,len);
if(result==-1)
{
printf("ensure the server is up\n");
perror("connect");
exit(1);
}
for(i=0,ch_send='A';i<5;i++,ch_send++){
if(write(sockfd,&ch_send,1)==-1)
{
perror("write");
exit(1);
}
if(read(sockfd,&ch_recv,1)==-1)
{
perror("read");
exit(1);
}else
printf("receive from server is %c\n",ch_recv);
}
close(sockfd);
return 0;
}