ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

linux之域套接字

linux之域套接字 域套接字属于本机 IPC 进程间通信只用于同一主机内多进程通信不支持跨主机。无需 IP 地址、端口号通信载体是 Linux 下s 类型套接字文件。数据经由内核空间完成进程之间的数据传输。域套接字通信也分为流式域套接字和报式域套接字。#includesys/types.h/* See NOTES */#includesys/socket.hintsocket(intdomain,inttype,intprotocol);功能为通信创建一个端点并返回该端点对应的文件描述符文件描述符的使用原则是最小未分配 原则 参数1协议族常用的协议族如下 Name Purpose Man page AF_UNIX,AF_LOCAL 本地通信同一主机的多进程通信 具体内容查看 man7unix AF_INET 提供IPv4的相关通信方式 具体内容查看 man7ip AF_INET6 提供IPv6的相关通信方式 具体内容查看 man7ipv6 参数2通信类型指定通信语义常用的通信类型如下 SOCK_STREAM 支持TCP面向连接的通信协议 SOCK_DGRAM 支持UDP面向无连接的通信协议 参数3通信协议当参数2中明确指定特定协议时参数3可以设置为0但是有多个协议共同使用 时需要用参数3指定当前套接字确定的协议 返回值成功返回创建的端点对应的文件描述符失败返回-1并置位错误码#includesys/types.h/* See NOTES */#includesys/socket.hintbind(intsockfd,conststructsockaddr*addr,socklen_t addrlen);功能为套接字分配名称给套接字绑定ip地址和端口号 参数1要被绑定的套接字文件描述符 参数2通用地址信息结构体对于不同的通信域而言使用的实际结构体是不同的该结构体的目的是为了强制类型转换防止警告 通信域为AF_UNIX而言本地通信structsockaddr_un{sa_family_t sun_family;/* 通信域AF_UNIX */charsun_path[UNIX_PATH_MAX];/* 通信使用的文件 */要求套接字文件不存在};参数3参数2的大小 返回值成功返回0失败返回-1并置位错误码判断一个文件是否存在于文件系统函数#includeunistd.hintaccess(constchar*pathname,intmode);功能判断给定的文件是否具有给的的权限 参数1要被判断的文件描述符 参数2要被判断的权限 R_OK:读权限 W_OK:写权限 X_OK:执行权限 F_OK:是否存在 返回值如果要被判断的权限都存在则返回0否则返回-1并置位错误码删除一个文件系统中的文件函数#includeunistd.hintunlink(constchar*path);功能删除指定的文件 参数要删除的文件路径 返回值成功删除返回0失败返回-1并置位错误码1、流式域套接字实现intmain(intargc,constchar*argv[]){//1、创建用于通信的客户端套接字文件描述符intcfdsocket(AF_UNIX,SOCK_STREAM,0);if(cfd-1){perror(socket error);return-1;}printf(socket success cfd%d\n,cfd);//2、绑定ip地址和端口号 如果没有绑定系统也不会自动绑定会给的一个随机文件if(access(./linux,F_OK)0){//说明文件已经存在需要将其进行删除操作if(unlink(./linux)-1){perror(unlink error);return-1;}}//2.1、填充要绑定的地址信息结构体structsockaddr_uncun;cun.sun_familyAF_UNIX;stcpy(cun.sun_path,./linux);//2.2、绑定工作if(bind(cfd,(structsockaddr*)cun,sizeof(cun))-1){perror(bind error);return-1;}printf(bind success\n);//3、连接服务器//3.1 填充要连接的服务器地址信息结构体structsockaddr_unsun;sun.sun_familyAF_UNIX;//通信域strcpy(sun.sun_path,./unix);//服务器套接字文件//3.2 连接工作if(connect(cfd,(structsockaddr*)sun,sizeof(sun))-1){perror(connect error);return-1;}printf(连接成功\n);//4、数据收发charwbuf[128];while(1){//清空容器bzero(wbuf,sizeof(wbuf));//从终端获取数据fgets(wbuf,sizeof(wbuf),stdin);//0wbuf[strlen(wbuf)-1]0;//将数据发送给服务器if(send(cfd,wbuf,sizeof(wbuf),0)-1){perror(send error);return-1;}//接受服务器发送过来的消息if(recv(cfd,wbuf,sizeof(wbuf),0)0){printf(对端已经下线\n);break;}printf(收到服务器消息为%s\n,wbuf);}//5、关闭套接字close(cfd);std::coutHello, World!std::endl;return0;}Unix 域套接字对比网络 socket不用 IP、端口使用套接字文件标识通信端点。通信域AF_UNIX地址结构体struct sockaddr_un。bind绑定的套接字文件必须预先不存在。客户端不手动 bind系统不会自动分配套接字文件不会生成乱码文件名。2、报式域套接字实现服务器端实现intmain(intargc,constchar*argv[]){//1、创建用于通信的套接字文件描述符intsfdsocket(AF_UNIX,SOCK_DGRAM,0);//SOCK_DGRAM表示基于udp通信方式if(sfd-1){perror(socket error);return-1;}printf(socket success sfd %d\n,sfd);//3//2、绑定套接字文件//判断套接字文件是否存在if(access(./unix,F_OK)0){//说明文件已经存在需要将其进行删除操作if(unlink(./unix)-1){perror(unlink error);return-1;}}//2.1 填充要绑定的ip地址和端口号结构体structsockaddr_unsun;sun.sun_familyAF_UNIX;//通信域strcpy(sun.sun_path,./unix);//套接字文件//2.2 绑定工作//参数1要被绑定的套接字文件描述符//参数2要绑定的地址信息结构体需要进行强制类型转换防止警告//参数3参数2的大小if(bind(sfd,(structsockaddr*)sun,sizeof(sun))-1){perror(bind error);return-1;}printf(bind success\n);//3、数据收发charrbuf[128];//定义容器接收对端的地址信息结构体structsockaddr_uncun;socklen_t socklensizeof(cun);while(1){//清空容器bzero(rbuf,sizeof(rbuf));//从客户端中读取消息if(recvfrom(sfd,rbuf,sizeof(rbuf),0,(structsockaddr*)cun,socklen)-1){perror(recvfrom error);return-1;}printf([%s]:%s\n,cun.sun_path,rbuf);//加个笑脸发给客户端strcat(rbuf,*_*);//将数据发送给客户端sendto(sfd,rbuf,strlen(rbuf),0,(structsockaddr*)cun,sizeof(cun));printf(发送成功\n);}//4、关闭套接字close(sfd);std::coutHello, World!std::endl;return0;}客户端端实现#includestdio.h#includestdlib.h#includeunistd.h#includesys/socket.h#includesys/un.h#includestring.hintmain(intargc,constchar*argv[]){//1、创建用于通信的套接字文件描述符intcfdsocket(AF_UNIX,SOCK_DGRAM,0);if(cfd-1){perror(socket error);return-1;}printf(socket success cfd %d\n,cfd);//填充服务端的地址信息目标地址不需要bindstructsockaddr_unsun_server;sun_server.sun_familyAF_UNIX;strcpy(sun_server.sun_path,./unix);charwbuf[128];charrbuf[128];while(1){bzero(wbuf,sizeof(wbuf));bzero(rbuf,sizeof(rbuf));printf(请输入要发送的数据);fgets(wbuf,sizeof(wbuf),stdin);//去掉fgets读到的换行符wbuf[strcspn(wbuf,\n)]\0;//发送数据给服务端if(sendto(cfd,wbuf,strlen(wbuf),0,(structsockaddr*)sun_server,sizeof(sun_server))-1){perror(sendto error);return-1;}//接收服务端回显应答structsockaddr_uncun;socklen_t socklensizeof(cun);if(recvfrom(cfd,rbuf,sizeof(rbuf),0,(structsockaddr*)cun,socklen)-1){perror(recvfrom error);return-1;}printf(服务器回复%s\n,rbuf);//输入quit退出if(strcmp(wbuf,quit)0){break;}}close(cfd);return0;}
返回列表