????????本地套接字(Unix域套接字)是用于在同一台机器上的进程之间进行通信的一种方式。它不涉及网络协议,而是直接在文件系统中创建一个套接字文件,进程可以通过该文件进行通信。
本地套接字的作用:本地的进程间通信????????有关系的进程间的通信????????没有关系的进程间的通信本地套接字实现流程和网络套接字类似,一般呢采用 TCP 的通信流程。
?
// 头文件: sys/un.h
#define UNIX_PATH_MAX 108
struct sockaddr_un {
sa_family_t sun_family; // 地址族协议 af_local
char sun_path[UNIX_PATH_MAX]; // 套接字文件的路径, 这是一个伪文件, 大小永远=0
};
// 本地套接字通信的流程 - tcp
// 服务器端
1. 创建监听的套接字
int lfd = socket(AF_UNIX/AF_LOCAL, SOCK_STREAM, 0);
2. 监听的套接字绑定本地的套接字文件 -> server端
struct sockaddr_un addr;
// 绑定成功之后,指定的sun_path中的套接字文件会自动生成。
bind(lfd, addr, len);
3. 监听
listen(lfd, 100);
4. 等待并接受连接请求
struct sockaddr_un cliaddr;
int cfd = accept(lfd, &cliaddr, len);
5. 通信
接收数据:read/recv
发送数据:write/send
6. 关闭连接
close();
// 客户端的流程
1. 创建通信的套接字
int fd = socket(AF_UNIX/AF_LOCAL, SOCK_STREAM, 0);
2. 监听的套接字绑定本地的IP 端口
struct sockaddr_un addr;
// 绑定成功之后,指定的sun_path中的套接字文件会自动生成。
bind(lfd, addr, len);
3. 连接服务器
struct sockaddr_un serveraddr;
connect(fd, &serveraddr, sizeof(serveraddr));
4. 通信
接收数据:read/recv
发送数据:write/send
5. 关闭连接
close();
服务端?
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/un.h>
int main() {
unlink("server.sock");
// 1.创建监听的套接字
int lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
if(lfd == -1) {
perror("socket");
exit(-1);
}
// 2.绑定本地套接字文件
struct sockaddr_un addr;
addr.sun_family = AF_LOCAL;
strcpy(addr.sun_path, "server.sock");
int ret = bind(lfd, (struct sockaddr *)&addr, sizeof(addr));
if(ret == -1) {
perror("bind");
exit(-1);
}
// 3.监听
ret = listen(lfd, 100);
if(ret == -1) {
perror("listen");
exit(-1);
}
// 4.等待客户端连接
struct sockaddr_un cliaddr;
int len = sizeof(cliaddr);
int cfd = accept(lfd, (struct sockaddr *)&cliaddr, &len);
if(cfd == -1) {
perror("accept");
exit(-1);
}
printf("client socket filename: %s\n", cliaddr.sun_path);
// 5.通信
while(1) {
char buf[128];
int len = recv(cfd, buf, sizeof(buf), 0);
if(len == -1) {
perror("recv");
exit(-1);
} else if(len == 0) {
printf("client closed....\n");
break;
} else if(len > 0) {
printf("client say : %s\n", buf);
send(cfd, buf, len, 0);
}
}
close(cfd);
close(lfd);
return 0;
}
客户端
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/un.h>
int main() {
unlink("client.sock");
// 1.创建套接字
int cfd = socket(AF_LOCAL, SOCK_STREAM, 0);
if(cfd == -1) {
perror("socket");
exit(-1);
}
// 2.绑定本地套接字文件
struct sockaddr_un addr;
addr.sun_family = AF_LOCAL;
strcpy(addr.sun_path, "client.sock");
int ret = bind(cfd, (struct sockaddr *)&addr, sizeof(addr));
if(ret == -1) {
perror("bind");
exit(-1);
}
// 3.连接服务器
struct sockaddr_un seraddr;
seraddr.sun_family = AF_LOCAL;
strcpy(seraddr.sun_path, "server.sock");
ret = connect(cfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if(ret == -1) {
perror("connect");
exit(-1);
}
// 4.通信
int num = 0;
while(1) {
// 发送数据
char buf[128];
sprintf(buf, "hello, i am client %d\n", num++);
send(cfd, buf, strlen(buf) + 1, 0);
printf("client say : %s\n", buf);
// 接收数据
int len = recv(cfd, buf, sizeof(buf), 0);
if(len == -1) {
perror("recv");
exit(-1);
} else if(len == 0) {
printf("server closed....\n");
break;
} else if(len > 0) {
printf("server say : %s\n", buf);
}
sleep(1);
}
close(cfd);
return 0;
}