一、实现流程
本地套接字的作用:进程间通信
有关系的进程间通信
没有关系的进程间通信
本地套接字实现和网络套接字类似,一般采用TCP通信流程
//本地套接字的流程 - TCP
//服务器端
1.创建监听的套接字
int lfd = socker(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 = socker(AF_UNIX/AF_LOCAL,SOCK_STREAM,0);
2.监听的套接字绑定本地的套接字文件 ->client端
struct sockaddr_un addr;
//绑定成功之后,指定的sun_path中的套接字文件会自动生成。
bind(lfd,addr,len);
3.连接服务器
connect(fd,&serveraddr,sizeof(serveraddr));
4.通信
接受数据:read/recv
发送数据:write/send
5.关闭连接
close();
二、代码实现
1.服务器
代码如下(示例):
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include<fcntl.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, 5);
if(ret == -1)
{
perror("listen");
exit(-1);
}
//4.等待客户端连接
struct sockaddr_un caddr;
int len = sizeof(caddr);
int cfd = accept(lfd, (struct sockaddr *)&caddr, &len);
if(cfd==-1)
{
perror("accept");
exit(-1);
}
printf("client socket filename: %s\n", caddr.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 close...\n");
break;
}else if(len>0)
{
printf("client say:%s\n", buf);
send(cfd, buf, len, 0);
}
}
close(cfd);
close(lfd);
return 0;
}
2.客户端
代码如下(示例):
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include<fcntl.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 saddr;
saddr.sun_family=AF_LOCAL;
strcpy(saddr.sun_path, "server.sock");
ret = connect(cfd, (struct sockaddr *)&saddr, sizeof(saddr));
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 close...\n");
break;
}else if(len>0)
{
printf("server say:%s\n", buf);
}
sleep(1);
}
close(cfd);
return 0;
}