作者:最傻的傻瓜z1998 | 来源:互联网 | 2023-07-13 22:43
参考文章: [1]Unix Domain Socket– IPC通信机制 [2]How fast are Unix domain sockets? [3]read()函数参数理解
一、Unix域的Socket通信及其优点 基于socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC 更有效率及可靠 :
不需要经过网络协议栈 不需要打包拆包、计算校验和、维护序号和应答等,可靠性更强 UNIX Domain Socket传输效率比通过loopback地址快将近一倍 二、预备知识 对于知识一,已经在前面介绍过了。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 int num_reverse ( int num) ; int main ( ) { unlink ( "server_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 ) ; 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 ( ) { 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 ) ; read ( sockfd, & num, 4 ) ; printf ( "get an integer from server: %d\n" , num) ; 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
四、验证结果 启动server端:
启动client端: