UNIX域套接字是进程间通信(IPC)的一种方式,不涉及网络协议栈,因此在同一台主机上的通信中,它比基于TCP/IP协议的网络套接字更快速、更高效。
逻辑如下:
服务器:
(1)socket();
socket(AF_UNIX, SOCK_STREAM, 0);
(2)bind();
/*
struct sockaddr_un {
sa_family_t sun_family;
char
};
sun_path[108];
*/
struct sockaddr_un serverAddr;
bzero(&serverAddr, sizeof(serverAddr));
serverAddr.sun_family = AF_UNIX;
//serverAddr.sun_sun_path = "./MyClientSockFile";//error:数组名是指针常量!
//做法1:
char *path = "./MyClientSockFile";
strcpy(serverAddr.sun_path, path);
//做法2:
//使用sprintf:将数据按照指定格式写入到指定的地址空间中去
sprintf(serverAddr.sun_path, "%s", path);
(3)listen();
(4)accept();
(5)send()/recv();
(6)close();
客户端:
(1)socket();
(2)保存服务器的地址信息
(3)connect();
(4)send()/recv();
(5)close();
逻辑如下:
服务器:
(1)socket();
(2)bind();
(3)recvfrom()/sendto();
(4)close();
客户端:
(1)socket();
(2)bind();//在UDP这边,客户端必须bind(因为通信时双方必须知道给哪个本地上的套接字文件收发数据)
(3)sendto()/recvfrom(); (4)close();
client.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, const char *argv[])
{
//创建数据报套接字
int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
printf("socket ok!\n");
//设置客户端地址
struct sockaddr_un clientAddr;
bzero(&clientAddr, sizeof(clientAddr));//清空地址结构
clientAddr.sun_family = AF_UNIX;
char *path_client = "./MyClientFile";
sprintf(clientAddr.sun_path, "%s", path_client);
//绑定客户端的地址信息(必须)
bind(sockfd, (struct sockaddr *)&clientAddr, sizeof(clientAddr));
printf("bind ok!\n");
//设置服务器地址
struct sockaddr_un serverAddr;
bzero(&serverAddr, sizeof(serverAddr));//清空地址结构
serverAddr.sun_family = AF_UNIX;
char *path_server = "./MyServerFile";
sprintf(serverAddr.sun_path, "%s", path_server);
char buf[1024];
int count;
while(1)
{
memset(buf, 0, sizeof(buf));
//发送业务给服务器
printf("请输入业务:\n");
//fgets(buf, sizeof(buf), stdin);
scanf("%s", buf);
sendto(sockfd, buf, strlen(buf), 0, \
(struct sockaddr *)&serverAddr, sizeof(serverAddr));
printf("sendto server ok!\n");
memset(buf, 0, sizeof(buf));
bzero(&serverAddr, sizeof(serverAddr));
//处理服务器的应答
recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
printf("服务器应答:[%s]\n", \
buf);
}
//关闭套接字
close(sockfd);
return 0;
}
server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, const char *argv[])
{
//创建数据报套接字
int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
printf("socket ok!\n");
//设置服务器地址
struct sockaddr_un serverAddr;
bzero(&serverAddr, sizeof(serverAddr));//清空地址结构
serverAddr.sun_family = AF_UNIX;
char *path_server = "./MyServerFile";
sprintf(serverAddr.sun_path, "%s", path_server);
//绑定服务器的地址信息
if(bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
{
return -1;
}
printf("bind ok!\n");
//设置客户端地址
struct sockaddr_un clientAddr;
bzero(&clientAddr, sizeof(clientAddr));//清空地址结构
int len = sizeof(clientAddr);
char buf[1024];
int count;
while(1)
{
//接收客户端发送的业务
if((count = recvfrom(sockfd, buf, sizeof(buf), 0, \
(struct sockaddr *)&clientAddr, &len)) < 0)
{
perror("read error");
return -1;
}
else
{
buf[count] = '\0';
printf("recvfrom client 业务[%s]\n", \
buf);
//给客户端应答
sendto(sockfd, "I am udp_server!", strlen("I am udp_server"), 0, \
(struct sockaddr *)&clientAddr, sizeof(clientAddr));
printf("sendto ack_client ok!\n");
}
}
//关闭套接字
close(sockfd);
return 0;
}
共享内存>UNIX域套接字>消息队列>管道