UNIX域套接字本地通信即在socket第一个参数中选择AF_LOCAL,socket是BSD提出的一种适用于所有的情况的进程间通信的方式,虽然现在多用于网络通信,但是本机内的进程间通信也是没有问题的,使用socket机制的UNIX域常用在前台进程和后台进程的通信。VS tcp/ip和udp/ip的socket在CS两端使用的读写sockfd函数不同,在UNIX域下,CS两端都使用read()/write()对socket进行读写。
模型

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
//服务器:
socket()
//创建socket
struct sockaddr_in
//准备通信sock文件
bind()
//绑定socket和addr
write()/read()
//进行通信
close()
//关闭socket
//客户端:
socket()
//创建socket
//准备通信地址:服务器准备的sock文件
connect()
//链接socket和通信地址
write()/read()
//进行通信
close()
//关闭socket
socket()
//创建网络端点,返回socket文件描述符,失败返回-1设errno
int socket(int domain, int type, int protocol);
domain :协议族(protocol family)(网络通讯(IP)还是本地通讯(xxx.socket))
AF_LOCAL本地通讯/AF_UNIX/
type :协议
SOCK_STREAM //流式套接字, 实现包括但不限于TCP协议,which is有序,可靠双向面向连接的字节流通信方式
SOCK_DGRAM //数据报套接字, 实现包括但不限于UDP协议, which is不可靠,无连接的数据报通信方式
protocol: 特殊协议, 一般给0
准备通信地址:
struct sockaddr{
//主要用于函数的形参类型, 很少定义结构体变量使用, 叫做通用的通信地址类型//$man bind
sa_family_t
sa_family;
char
sa_data[
14];
}
struct sockaddr_un{
//准备本地通信的通信地址 //$man un.h
sa_family_t
sun_family;
//协议族,就是socket()的domain的AF_LOCAL
char
sun_path[];
//文件的路径
}
bind()
//把通信地址和socket文件描述符绑定,用在服务器端,成功返回0,失败返回-1设errno
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd: socket文件的fd(returned by socket())
addr: 需要强制类型转换成socketaddr_un或soketaddr_in, 参见上
addrlen: 通信地址的大小, 使用sizeof();
connect():
//初始化一个socket的连接,用在客户端,成功返回0,失败返回-1设errno
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
sockfd: socket文件的fd(returned by socket())
addr: 需要强制类型转换成socketaddr_un或soketaddr_in, 参见上
addrlen: 通信地址的大小, 使用sizeof();
例子
//UNIX域数据报socket进程间通信
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
//1. create socket
int sockfd=socket(AF_LOCAL,SOCK_DGRAM,
0);
if(
-1==sockfd)
perror(
"socket"),
exit(
-1);
printf(
"create socket successfully\n");
//2. prepare communication addr
struct sockaddr_un addr;
addr.sun_family=AF_LOCAL;
strcpy(addr.sun_path,
"a.sock");
//会自动创建a.sock文件
//3. bind socket and addr
int res=bind(sockfd,(
struct sockaddr*)&addr,
sizeof(addr));
//客户端是connect()
if(
-1==res)
perror(
"bind"),
exit(
-1);
printf(
"bind successfully\n");
//4. communicate
char buf[
100]={
0};
res=read(sockfd,&buf,
sizeof(buf));
//客户端是write()
if(
-1==res)
perror(
"read"),
exit(
-1);
printf(
"data sent by client:%s,size is %d\n",buf,
sizeof(buf));
//5. close socket
res=close(sockfd);
if(
-1==res)
perror(
"close"),
exit(
-1);
printf(
"close successfully\n");
return 0;
}