本地套接字通信
利用本地套接字,也可以进程间通信。
本地套接字和有名管道一样都利用伪文件
管道的文件类型是p
本地套接字的文件类型是s。
当调用bind函数后,就会生成本地套接字对应的伪装文件
srwxr-xr-x 1 ys ys 0 7月 2 10:55 server.socket
srwxr-xr-x 1 ys ys 0 7月 2 10:55 client.socket
和网络套接字不同的地方是:
- 使用的结构体不一样,本地套接字使用:
struct sockaddr_un{
sun_family;//AF_LOCAL
sun_path;//本地套接字对应的伪装文件的名字,可以加路径
}
- 客户都也必须调用bind函数
- 需要头文件:sys/un.h
- 需要提前删除上次执行生成的伪装文件,如果不删除的话,bind函数会执行失败,错误信息:Address already in use
接收端例子:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
unlink("server.socket");
struct sockaddr_un serv;
strcpy(serv.sun_path, "server.socket");
serv.sun_family = AF_LOCAL;
int ret = bind(fd, (struct sockaddr*)&serv, sizeof(serv));
if(ret == -1){
perror("bind error");
exit(1);
}
listen(fd, 64);
struct sockaddr_un cli;
socklen_t len;
int cfd = accept(fd, (struct sockaddr*)&cli, &len);
while(1){
char buf[64];
ret = recv(cfd, buf, sizeof(buf), 0);
if(ret == -1){
perror("recv error");
exit(1);
}
else if(ret == 0){
printf("client closed
");
close(cfd);
}
printf("clinet path:%s
", cli.sun_path);
write(STDOUT_FILENO, buf, ret);
}
close(cfd);
close(fd);
}
发送端例子:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(){
int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
unlink("client.socket");
struct sockaddr_un cli;
strcpy(cli.sun_path, "client.socket");
cli.sun_family = AF_LOCAL;
if(bind(fd, (struct sockaddr*)&cli, sizeof(cli)) == -1){
perror("bind cli error");
exit(1);
}
struct sockaddr_un to;
to.sun_family = AF_LOCAL;
strcpy(to.sun_path, "server.socket");
int ret = connect(fd, (struct sockaddr*)&to, sizeof(to));
int cnt = 0;
while(1){
char buf[64] = {0};
sprintf(buf, "cnt = %d", cnt++);
int ret = send(fd, buf, sizeof(buf), 0);
if(ret == -1){
perror("send error");
exit(1);
}
sleep(1);
}
}