本地套接字
本地套接字的作用: 本地的进程间通信 可以实现 有关系的进程间的通信 和 没有关系的进程间的通信 本地套接字实现流程和网络套接字类似,一般采用TCP的通信流程。
#define UNIX_PATH_MAX 108
struct sockaddr_un {
sa_family_t sun_family;
char sun_path[UNIX_PATH_MAX];
};
1. 创建监听的套接字
int lfd = socket(AF_UNIX/AF_LOCAL, SOCK_STREAM, 0); --AF_UNIX和AF_LOCAL表示本地的套接字
2. 监听的套接字绑定本地的套接字文件 -> server端
struct sockaddr_un addr; --本地套接字使用socka
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;
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"); --一开始进来就删掉,然后后面重新生成
int lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
if(lfd == -1) {
perror("socket");
exit(-1);
}
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);
}
ret = listen(lfd, 100);
if(ret == -1) {
perror("listen");
exit(-1);
}
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);
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"); --一开始进来就删掉,然后后面重新生成
int cfd = socket(AF_LOCAL, SOCK_STREAM, 0);
if(cfd == -1) {
perror("socket");
exit(-1);
}
struct sockaddr_un addr;
addr.sun_family = AF_LOCAL;
strcpy(addr.sun_path, "client.sock"); --sun_path套接字文件路径
int ret = bind(cfd, (struct sockaddr *)&addr, sizeof(addr));
if(ret == -1) {
perror("bind");
exit(-1);
}
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);
}
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;
}
运行程序:
服务端:
? 运行服务端之后,绑定成功了,会产生一个serve.sock文件,就是我们设置的那个路径。
客户端:
客户端也生成了一个client.sock;
断开再打开服务器端:
在本地套接字中,可以认为是受client.sock和server.sock的影响;
使用unlink函数解决;
在服务端和客户端的前面分别添加unlink函数 --在系统中删除一个文件:
unlink("client.sock");
unlink("server.sock");
|