本地套接字的作用:本地的进程间通信
- 有关系的进程间的通信
- 没有关系的进程间的通信
- 本地套接字实现流程和网络套接字类似,一般呢采用
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
// 删除文件
unlink("server.sock")
unlink("client.sock")
// 服务器端
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
#include
#include
#include
#include
using namespace std;
int main() {
// 删除文件
unlink("server.sock");
// 客户端创建监听描述符
int lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
// 绑定本地的套字节文件
sockaddr_un server_addr;
server_addr.sun_family = AF_LOCAL;
strcpy(server_addr.sun_path, "server.sock");
bind(lfd, (sockaddr *)&server_addr, sizeof(server_addr));
// 监听客户端是否连接
listen(lfd, 8);
// 接收获取客户端的信息
sockaddr_un client_addr;
socklen_t len = sizeof(client_addr);
int cfd = accept(lfd, (sockaddr *)&client_addr, &len);
// 输出客户端的套字节
printf("client sock filename: %s\n", client_addr.sun_path);
// 进行通信
char recvBuf[128];
while (1) {
int len = recv(cfd, recvBuf, sizeof(recvBuf), 0);
if (len == -1) {
perror("recv");
exit(-1);
} else if (len == 0) {
cout << "client closed..." << endl;
break;
} else if (len > 0) {
printf("I am server, data: %s\n", recvBuf);
send(cfd, recvBuf, strlen(recvBuf) + 1, 0);
}
}
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
int main() {
// 删除文件
unlink("client.sock");
// 创建通信的文件描述符
int cfd = socket(AF_LOCAL, SOCK_STREAM, 0);
// 绑定本地套接字文件
sockaddr_un client_addr;
client_addr.sun_family = AF_LOCAL;
strcpy(client_addr.sun_path, "client.sock");
bind(cfd, (sockaddr *)&client_addr, sizeof(client_addr));
// 连接服务器
sockaddr_un server_addr;
server_addr.sun_family = AF_LOCAL;
strcpy(server_addr.sun_path, "server.sock");
// 向服务端发起连接
connect(cfd, (sockaddr *)&server_addr, sizeof(server_addr));
char sendBuf[128];
int num = 0;
while (1) {
// 向服务端发送文件
sprintf(sendBuf, "hello server %d\n", num ++ );
send(cfd, sendBuf, strlen(sendBuf) + 1, 0);
int len = recv(cfd, sendBuf, sizeof(sendBuf), 0);
if (len == -1) {
perror("recv");
exit(-1);
} else if (len == 0) {
cout << "client closed..." << endl;
exit(-1);
} else if (len > 0) {
printf("I am server, data: %s\n", sendBuf);
}
sleep(1);
}
return 0;
}