UNIX域套接字(UDS) 原理及应用
UNIX域socket实现本地进程间通信,需要一个进程作为服务器端,一个进程作为客户端,使用方法有点像socket网络,但又不经过网络底层的那些东西。与网
UNIX域套接字(UDS):UNIX Domain Socket UNIX域socket实现本地进程间通信,需要一个进程作为服务器端,一个进程作为客户端,使用方法有点像socket网络,但又不经过网络底层的那些东西。与网络编程最不一样的地方是服务器端bind的时候用的是sockaddr_un结构,客户端connect的时候用的也是sockaddr_un结构,而不是sockaddr_in或sockaddr。而对于sockaddr_un结构,重点是给它提供一个bind()函数生成的socket类型文件的路径,即sockaddr_un.sun_path的值。并且客户端与服务器端的这个sockaddr_un结构的sun_path是一致的,通常这个路径是众所众知的,就像百度的域名那样。 经过bind,listen,accept,和connect后,两进程就通过读写socket文件描述符来通信,具体是服务器端读写accept返回的socket文件描述符,客户端读写经过connect处理后的文件描述符。 使用流程分析: 一、服务器端通信过程分析 服务器端基本遵循面向连接的socket数据流通信过程。 1、调用socket()函数,建立socket对象,指定通信协议为AF_UNIX。 2、调用bind()函数,将创建的socket对象与bind()函数产生的那个socket类型的文件server_socket P绑定。 UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,其地址用结构体sockaddr_un表示, 网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在unix进程通信,且已被link,则bind()错误返回。一个套接字只能绑定到一个路径上,同样的,一个路径也只能被一个套接字绑定。 sockaddr_un结构的sun_path成员包含一路径名,当我们将一地址绑定至UNIX域套接字时,系统用该路径名创建一类型为S_IFSOCK的文件。该文件仅用于向客户端进程告知套接字名字,该文件不能打开,也不能由应用程序用于通信,当关闭套接字时,并不自动删除该文件,所以我们必须确保在应用程序终止前,对该文件执行解除链接操作(unlink(path)),或删除该文件。 struct sockaddr_un结构有两个参数:sun_family、sun_path。sun_family只能是AF_LOCAL或AF_UNIX;而sun_path就是本地文件的路径。 3、调用listen()函数,使socket对象处于监听状态,并设置监听队列大小。 4、服务器端监听到该请求,在客户端发出请求后,accept()函数接收请求,返回新文件描述符,从而建立连接。 5、服务器端调用read()函数接收数据(开始处于阻塞状态,等待客户端发送数据,因此,客户端在编程是需要首先发送数据,接收到数据后,输出接收到的数据)。 6、调用write()函数发送数据到客户端。 7、通信完成后,调用close()函数关闭socket对象;unlink(sockaddr_un.sun_path)。 二、客户端通信过程分析 客户端基本遵循面向连接的socket数据流通信过程。 1、调用socket()函数,建立socket对象,指定相同通信协议。 2、客户端调用connect()函数,向服务器端发起连接请求。 3、在得到服务器端允许后,首先调用write()函数向服务器端发送消息(因服务器端循环体中首先是接收数据)。 4、调用read()函数接收数据。 5、通信完成后,调用close()函数关闭socket对象。 具体使用例子: 这一例子实现一端发送字符,一端发送字符串。 服务器端源码: socket_local_server.c: #include #include #include #include #include #include int main(int argc,char *argv[]) { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_un server_address; struct sockaddr_un client_address; int i,byte; char ch_send,recv_buf[128]; unlink("server_socket");//解除原有server_socket对象链接 server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);//创建socket,指定通信协议为AF_UNIX,数据方式SOCK_STREAM //配置server_address server_address.sun_family = AF_UNIX; strcpy(server_address.sun_path, "server_socket"); server_len = sizeof(server_address); bind(server_sockfd, (struct sockaddr *)&server_address, server_len); listen(server_sockfd, 5); printf("server waiting for client connect\n"); client_len = sizeof(client_address); //accept函数接收客户端求情,存储客户端地址信息、客户端地址大小 client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address, (socklen_t *)&client_len); printf("the server wait form client data\n"); for(i=0,ch_send='1';i { //从client_sockfd读取客户端发来的消息 if((byte=read(client_sockfd, recv_buf, sizeof(recv_buf)))==-1) { perror("read"); exit(EXIT_FAILURE); } printf("the massage receiver from client is: %s\n",recv_buf); sleep(1); //向客户端发送消息 if((byte=write(client_sockfd,&ch_send,1))==-1) { perror("write"); exit(EXIT_FAILURE); } } close(client_sockfd); unlink("server socket"); } 客户端源码: socket_local_client.c: #include #include #include #include #include #include int main(int argc,char *argv[]) { int sockfd; int len; struct sockaddr_un address; int result; int i,byte; char send_buf[128],ch_recv; if((sockfd = socket(AF_UNIX, SOCK_STREAM, 0))==-1)//创建socket,指定通信协议为AF_UNIX,数据方式SOCK_STREAM { perror("socket"); exit(EXIT_FAILURE); } //配置server_address address.sun_family = AF_UNIX; strcpy(address.sun_path, "server_socket"); len = sizeof(address); result = connect(sockfd, (struct sockaddr *)&address, len); if(result == -1) { printf("ensure the server is up\n"); perror("connect"); exit(EXIT_FAILURE); } for(i=0;i { sprintf(send_buf,"client massage %d",i);//用sprintf事先把消息写到send_buf if((byte=write(sockfd, send_buf, sizeof(send_buf)))==-1) { perror("write"); exit(EXIT_FAILURE); } if((byte=read(sockfd,&ch_recv,1))==-1) { perror("read"); exit(EXIT_FAILURE); } printf("receive from server data is: %c\n",ch_recv); } close(sockfd); return 0; } 运行结果: 服务器端: book@book-desktop:~/workspace/zongde/chapter17$ ./socket_local_server server waiting for client connect the server wait form client data the massage receiver from client is: client massage 0 the massage receiver from client is: client massage 1 the massage receiver from client is: client massage 2 the massage receiver from client is: client massage 3 the massage receiver from client is: client massage 4 book@book-desktop:~/workspace/zongde/chapter17$ 客户端: book@book-desktop:~/workspace/zongde/chapter17$ ./socket_local_client receive from server data is: 1 receive from server data is: 2 receive from server data is: 3 receive from server data is: 4 receive from server data is: 5 book@book-desktop:~/workspace/zongde/chapter17$ (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |