《UNIX环境高级编程》笔记--UNIX域套接字
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了《UNIX环境高级编程》笔记--UNIX域套接字,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4021字,纯文字阅读大概需要6分钟。
内容图文
1.非命名的UNIX域套接字
UNIX套接字用于在用一台机器上运行的进程之间通信。UNIX套接字比因特网域套接字的效率更高。UNIX与套接字提供和
数据报两种接口,UNIX域数据报服务是可靠的,就不会丢失消息也不会传递出错。UNIX域套接字是套接字和管道之间的混合物。
为了创建一对非命名的,相互连接的UNXI域套接字,用户可以使用socketopair函数。
#include<sys/socket.h> int socketpari(int domain, int type, int protocol, int sockfd[2]); //若成功则返回0,出错则返回-1.实践:
#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <string.h> int main(void){ int fd[2]; int pid; char wbuf[16] = "1234567890"; char rbuf[16]; if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0){ perror("socketpair"); return -1; } if((pid = fork())<0){ perror("fork"); return -1; }else if(pid == 0){ //child close(fd[0]); if(write(fd[1],wbuf,strlen(wbuf)) < 0){ perror("write"); exit(-1); } }else{ //parent close(fd[1]); if(read(fd[0],rbuf,16) < 0){ perror("read"); exit(-1); } printf("%s\n",rbuf); } return 0; }执行结果:
yan@yan-vm:~$ ./a.out
1234567890
2.命名UNIX域套接字
虽然socketpair函数创建相互连接的一对套接字,但是每一个套接字都没有名字。这意味着无关进程不能使用它们。
我们可以命名unix域套接字,并可将其用于告示服务。但是要注意的是,UNXI与套接字使用的地址不同与因特网域套接字。
UNIX域套接字的地址由sockaddr_un结构表示。
在linux2.4.22中,sockaddr_un结构按下列形式定义在有文件<sys/un.h>中。
struct sockaddr_un{
sa_family_t sun_family; //AF_UNIX
char sun_path[108]; //pathname
};
sun_path成员包含一路经名,当我们将一个地址绑定至UNIX域套接字时,系统用该路经名创建一类型为S_IFSOCK文件。
该文件仅用于向客户进程告知套接字名字。该文件不能打开,也不能由应用程序用于通信。
如果当我们试图绑定地址时,该文件已经存在,那么bind请求失败。当关闭套接字时,并不自动删除该文件,所以我们必须
确保在应用程序终止前,对该文件执行解除链接操作。
服务器进程可以使用标准bind、listen和accept函数,为客户进程安排一个唯一UNIX域连接。客户进程使用connect与服务器
进程连接;服务器进程接受了connect请求后,在服务器进程和客户进程之间就存在了唯一连接。这种风格和因特网套接字
的操作很像。
实践:
server.c
#include <stdio.h> #include <sys/socket.h> #include <sys/un.h> #include <string.h> int main(void){ int fd,clientfd; int client_addr_len = sizeof(struct sockaddr_un); struct sockaddr_un un,clientun; char path[32]="serversocketfile"; int addr_len = sizeof(struct sockaddr_un); char rbuf[32]; char wbuf[32] = "i am server."; //create a UNIX domain stream socket if((fd = socket(AF_UNIX,SOCK_STREAM,0)) < 0){ perror("socket"); return -1; } //in case it already exists unlink(path); //fill in socket address structure memset(&un, 0, sizeof(un)); un.sun_family = AF_UNIX; strncpy(un.sun_path,path,32); //bind the name to the descriptor if(bind(fd, (struct sockaddr*)&un, addr_len) < 0){ perror("bind"); return -1; } if(listen(fd, 10) < 0){ perror("listen"); return -1; } if((clientfd = accept(fd,(struct sockaddr*)&clientun,(socklen_t*)&client_addr_len)) < 0 ){ perror("accept"); return -1; } printf("client is:%s\n",clientun.sun_path); if(read(clientfd,rbuf,32) < 0){ perror("read"); return -1; } printf("receive msg:%s\n",rbuf); if(write(clientfd,wbuf,strlen(wbuf)+1) < 0){ perror("write"); return -1; } unlink(path); return 0; }
client.c
#include <stdio.h> #include <sys/un.h> #include <sys/socket.h> #include <string.h> int main(void){ int fd; struct sockaddr_un un; char path[32] = "clientsocketfile"; char serverpath[32] = "serversocketfile"; int addr_len = sizeof(struct sockaddr_un); char wbuf[32] = "i am client."; char rbuf[32]; if((fd = socket(AF_UNIX,SOCK_STREAM,0))<0){ perror("socket"); return -1; } memset(&un,0,sizeof(un)); un.sun_family = AF_UNIX; strncpy(un.sun_path,path,32); unlink(path); if(bind(fd,(struct sockaddr*)&un,addr_len)<0){ perror("bind"); return -1; } //fill socket adress structure with server‘s address memset(&un,0,sizeof(un)); un.sun_family = AF_UNIX; strncpy(un.sun_path,serverpath,32); if(connect(fd,(struct sockaddr*)&un,addr_len) < 0){ perror("connect"); return -1; } if(write(fd,wbuf,strlen(wbuf)+1)<0){ perror("write"); return -1; } if(read(fd,rbuf,32) < 0){ perror("write"); return -1; } printf("receive msg:%s\n",rbuf); unlink(path); return -1; }
先运行server,再运行client。
运行结果:server.c:
yan@yan-vm:~/apue$ ./unixserver
client is:clientsocketfile
receive msg:i am client.
client.c:
yan@yan-vm:~/apue$ ./unixclient
receive msg:i am server.
原文:http://blog.csdn.net/todd911/article/details/20285711
内容总结
以上是互联网集市为您收集整理的《UNIX环境高级编程》笔记--UNIX域套接字全部内容,希望文章能够帮你解决《UNIX环境高级编程》笔记--UNIX域套接字所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。