参考文章:
[1]Unix Domain Socket– IPC通信机制
[2]How fast are Unix domain sockets?
[3]read()函数参数理解
基于socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC 更有效率及可靠 :
对于知识一,已经在前面介绍过了。Linux文件操作函数用到了两个:read()和write()。简单介绍一下:
read - 从文件描述符里读取数据
#include
ssize_t read(int fd, void *buf, size_t count);
fd:文件描述符,对于本文而言是socket套接字
buf:缓冲区指针
count:预期读取的字节数
返回值:表示实际读到的字节数(字符串结束符 '\0’不算)
write - 从文件描述符里写入数据
#include
ssize_t read(int fd, void *buf, size_t count);
fd:文件描述符,对于本文而言是socket套接字
buf:缓冲区指针
count:预期写入的字节数
返回值:表示实际写入的字节数(字符串结束符 '\0’不算)
程序的功能是实现客户端发送一个整型数据,服务端返回一个倒序的整型数据。
需要解决的问题:
数据处理部分函数实现:
int num_reverse(int num)
{
int S=0,sum=0;
while(num)
{
S=num%10;
sum=10*sum+S;
num = num / 10;
}
return sum;
}
服务端函数:
#include
#include
#include
#include
#include
#include
#include //define the sockaddr_un structure
int num_reverse(int num);
int main()
{
/* 断开之前的socket文件 */
unlink("server_socket");
/* 创建一个socket */
int server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un server_addr;
server_addr.sun_family = AF_UNIX;
strcpy(server_addr.sun_path, "server_socket");
/* 与本地文件进行绑定 */
bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
/* 监听 */
if(listen(server_sockfd, 5)<0);
{
perror("Listen failed");
}
int client_sockfd;
struct sockaddr_un client_addr;
socklen_t len = sizeof(client_addr);
while(1)
{
printf("server waiting:\n");
/* 接受一个客户端的链接 */
client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &len);
/*数据交换 */
read(client_sockfd, &num, 4);
printf("get an integer from client: %d\n", num);
num=num_reverse(num);
write(client_sockfd, &num, 4);
/* 关闭socket */
close(client_sockfd);
}
return 0;
}
int num_reverse(int num)
{
int S=0,sum=0;
while(num)
{
S=num%10;
sum=10*sum+S;
num = num / 10;
}
return sum;
}
客户端:
#include
#include
#include
#include
#include
#include
#include
int main()
{
/* 创建一个socket */
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un address;
address.sun_family = AF_UNIX;
strcpy(address.sun_path, "server_socket");
/*从键盘读取需要转置的整数*/
int num;
printf("Please enter the num to reverse:\n");
/* 链接至服务端 */
int result = connect(sockfd, (struct sockaddr *)&address, sizeof(address));
if(result == -1)
{
perror("connect failed: ");
exit(1);
}
/* 数据处理 */
write(sockfd, &num, 4);//一个int 4个字节
read(sockfd, &num, 4);
printf("get an integer from server: %d\n", num);
/* 关闭socket */
close(sockfd);
return 0;
}
makefile:
all:server.c client.c
gcc -g -Wall -o server server.c
gcc -g -Wall -o client client.c
clean:
rm -rf *.o server client
启动client端:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pHWYXMXr-1592040111330)(https://note.youdao.com/yws/api/personal/file/WEB8dc5bed0d11b73a1839fb15db352e6df?method=download&shareKey=3fa0896e980aa53895379783ead57bbb)]