UNIX 域协议(本地通信协议)

这篇具有很好参考价值的文章主要介绍了UNIX 域协议(本地通信协议)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

        Unix 域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务通信的一种方式。是进程间通信(IPC)的一种方式。
        它提供了两类套接字:字节流套接字 SOCK_STREAM(有点像 TCP)和数据报套接字 SOCK_DGRAM(有点像 UDP)
        UNIX 域数据报服务是可靠的,不会丢失消息,也不会传递出错。
        IP 协议标识客户服务器是通过 IP 地址和端口号实现的,UNIX 域协议中用于标识客户机和服务器的协议地址的是普通文件系统中的路径名。
UNIX 域协议的特点:
        1.UNIX 域套接字域 TCP 套接字相比,在同一台主机的传输速度前者是后者的两倍 。UNIX 域套接字仅仅复制数据,并不执行协议处理,不需要添加或删除网络报头,无需计算校验和,不产
生顺序号,也不需要发送确认报文
        2.UNIX 域套接字可以在同一台主机上各进程之间传递文件描述符
        3.UNIX 域套接字域传统套接字的区别是用路径名表示协议族的描述
UNIX 域协议地址
#define UNIX_PATH_MAX 108
struct sockaddr_un
{
    __kernel_sa_family_t sun_family; /* 通信协议 AF_UNIX / AF_LOCAL */
    char sun_path[UNIX_PATH_MAX]; /* pathname */
    //UNIX 域协议的地址,是以'\0'结束的本地文件系统中的绝对路径名
    //会自动的创建不需要提前创建
};
UNIX 域协议用于本地进程间通信的编程流程和 TCP/UDP 一样,只不过具体的协议地址是使
用文件路径名
        Server:先创建套接字 -> 绑定地址 -> 监听 -> accept 客户端连接 -> 连接成功开始通信 -> 关闭套接字
        Client:先创建套接字 ->绑定地址-> 连接 server -> 开始通信 -> 关闭套接字。

UNIX 域协议之进程间通信方式一:socketpair 函数

【头文件】
#include <sys/types.h>
#include <sys/socket.h>
【函数原型】
int socketpair(int domain, int type, int protocol, int sv[2]);
【函数功能】
        此函数只用于 Unix 域套接口,它的 domain 必须是 AF_LOCAL,protocol 参数必须为 0,type 可以是 SOCK_STREAM 也可以是 SOCK_DGRAM,它与调用 pipe 创建的普通管道类似,差别在 于普通管道只能进行单向读或单向写,而该管道是全双工的,可以单向读写。
【参数含义】
        [domain]: 表示协议族,在 Linux 下只能为 AF_LOCAL 或者 AF_UNIX 。(自从 Linux 2.6.27 后也支持 SOCK_NONBLOCK 和 SOCK_CLOEXEC)
        [type]: 表示协议,可以是 SOCK_STREAM 或者 SOCK_DGRAM。SOCK_STREAM 是基于TCP 的,而 SOCK_DGRAM 是基于 UDP 的
        [protocol]: 表示类型,只能为 0
        [sv]: 套节字柄对,该两个句柄作用相同,均能进行读写双向操作
【返回值】
        
        0 为创建成功,-1 为创建失败,并且 errno 来表明特定的错误号,具体错误号如下所述:
        EAFNOSUPPORT:本机上不支持指定的 address。 EFAULT: 地址 sv 无法指向有效的进程地址空间内。
        EMFILE: 已经达到了系统限制文件描述符,或者该进程使用过量的描述符。
        EOPNOTSUPP:指定的协议不支持创建套接字对。
        EPROTONOSUPPORT:本机不支持指定的协议。
【备注】
        1、该函数只能用于 UNIX 域( LINUX )下。
        2、只能用于有亲缘关系的进程(或线程)间通信。
        3、所创建的套节字对作用是一样的,均能够可读可写(而管道 PIPE 只能进行单向读写)。
        4、在读的时候,管道内必须有内容,否则将会阻塞;简而言之,该函数是阻塞的。
【示例代码】
/*socketpair1.c*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
int main ()
{
    int sv[2];
    int result = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
    if (result < 0){
        exit(1);
    }
    printf("sv[0] is : %d \n", sv[0]); //这两个套节字句柄并不相同,但作用是一样的
    printf("sv[1] is : %d \n", sv[1]);
    if (fork())
    { 
        /* 父进程 */
        int val = 0;
        pid_t pid = getpid(); 
        close(sv[1]); //父进程关闭 sv[1]的读写权限
        while (1)
        { 
            ++val;
            printf("%d send message: %d\n", pid, val); 
            write(sv[0], &val, sizeof(val)); //父进程向管道里写数据
            //也可以去读
            // read(sv[0], &val, sizeof(val)); //如果字进程不写数据,将会导致此处堵塞
            //printf("%d receive message: %d\n", pid, val);
            sleep(1);
        }
    }
    else
    { 
        /*子进程*/
        int val = 0;
        close(sv[0]); //字进程关闭 sv[0]的读写权限
        pid_t pid = getpid(); 
        while(1)
        {
            read(sv[1], &val, sizeof(val)); //字进程从管道中取数据
            printf("%d receive message: %d\n", pid, val);
            // printf("%d receive message: %d\n", pid, val); 
            //也可以写
            // write(sv[1], &val, sizeof(val));
        }
    }
}

UNIX 域协议之进程间通信方式二:套接字通信方式

        UNIX 域协议进行本地通信的方式和 TCP、UDP 很类似,下面就以 UNIX 域协议的流式套接字来写一个客户端和服务器间通信的例子,使用流式套接字,则本地间的通信方式就要类似于 TCP,这样的通信方式同时也具有 TCP 通信的特点。
客户端示例程序:
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include<netinet/in.h> //为了使用 IPV4 地址结构体
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>

#define UNIX_PATH_PS "/home/china/sockp1" //连接的套接字地址
#define UNIX_PATH_PC "/home/china/sockp2" //绑定的套接字地址

int main(int argc,char *argv[])
{
    system("rm /home/china/sockp2"); //防止文件重名

    //1.创建一个套接字
    int sockfd = socket(AF_UNIX, SOCK_STREAM,0); //创建一个本地通信 UNIX 流式套接字
    if(-1 == sockfd)
    {
        perror("create socket failed");
        exit(-1);
    }

    //2.绑定一个通信地址(让服务器能看到我),可不绑定
    struct sockaddr_un local; 
    memset(&local,0,sizeof(struct sockaddr_un)); //清空结构体
    local.sun_family = AF_UNIX;
    strcpy(local.sun_path,UNIX_PATH_PC);
    int ret = bind(sockfd,(struct sockaddr*)&local,sizeof(local));
    if(ret == -1)
    {
        perror("bind error");
        exit(-1);
    }
    printf("bind success\n");
    //连接目标服务器
    struct sockaddr_un saddr; //保存目标服务器的地址(本地的文件名)
    memset(&saddr,0,sizeof(struct sockaddr_un)); //清空结构体
    saddr.sun_family = AF_UNIX;
    strcpy(saddr.sun_path,UNIX_PATH_PS);
    ret = connect(sockfd, (struct sockaddr*)&saddr,sizeof(saddr)); //请求连接目标服务器
    if(ret == -1)
    {
        perror("connect error");
        exit(-1);
    }
    printf("connect success\n");
    char buf[1024] = {0};
    //读取信息
    ret = recv(sockfd,buf,1024, 0);
    if(ret == -1)
    {
        perror("recv error");
    }
    printf("recv size:%d,recv data:%s\n",ret,buf);
    //发送信息
    ret = sendto(sockfd,"byebye",6,0,NULL,0);
    if(ret == -1)
    {
        perror("sendto error");
    }
    printf("sendto size:%d\n",ret);
    //关闭套接字
    shutdown(sockfd,SHUT_RDWR);
    close(sockfd);
    return 0;
}
服务器程序示例:
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include<netinet/in.h> //为了使用 IPV4 地址结构体
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define UNIX_PATH_PS "/home/china/sockp1"

int main(int argc,char *argv[])
{
    system("rm /home/china/sockp1"); //保证该文件没有被使用

    //1.创建一个套接字
    int sockfd = socket(AF_UNIX, SOCK_STREAM,0); //创建一个本地通信UNIX 流式套接字
    if(-1 == sockfd)
    {
        perror("create socket failed");
        exit(-1);
    }

    //2.绑定一个通信地址(作为服务器本身的地址)
    struct sockaddr_un local; //保存服务器的地址(文件名)
    memset(&local,0,sizeof(struct sockaddr_un)); //清空结构体
    local.sun_family = AF_UNIX;
    strcpy(local.sun_path,UNIX_PATH_PS);
    int ret = bind(sockfd,(struct sockaddr*)&local,sizeof(local)); //绑定服务器的地址
    if(ret == -1)
    {
        perror("bind error");
        exit(-1);
    }
    printf("bind success\n");

    //3.开启对一个套接字的监听
    listen(sockfd,250);

    //4.等待客户端的连接
    while(1)
    {
        struct sockaddr_un caddr; //保存客户端的地址(文件名)
        socklen_t len = sizeof(caddr);
        int confd = accept(sockfd,(struct sockaddr*)&caddr,&len); //阻塞等待客户端连接
        if(confd > 0) //客户端连接成功,返回一个连接套接字专门用来和客户端通信
        {
            //一个客户端连接成功.开一个进程/线程去处理这个连接
            printf("client path:%s\n",caddr.sun_path);
            ret = sendto(confd,"nishiliangzaima?",20,0,NULL,0); //发送消息
            if(ret == -1)
            {
                perror("sendto error");
            }
            char buf[1024] = {0};
            ret = read(confd,buf,1024); //接收消息
            if(ret <= 0)
            {
                perror("recv error");
            }
            printf("recv size:%d,recv data:%s\n",ret,buf);
            close(confd);//关闭连接套接字
        }
    }
    //关闭套接字
    shutdown(sockfd,SHUT_RDWR);
    close(sockfd);
    return 0;
}

文章来源地址https://www.toymoban.com/news/detail-719183.html

到了这里,关于UNIX 域协议(本地通信协议)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【网络编程】网络通信基础——简述TCP/IP协议

    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程的一点学习心得,欢迎大家在评论区交流讨论💌 ip地址简单来说就是用来描述网络上一个设备的所在位置。 端

    2024年02月04日
    浏览(56)
  • 【Java】--网络编程:基于TCP协议的网络通信

    TCP协议(Transmission Control Protocol),即传输控制协议,是一种 面向连接 的, 可靠 的,基于 字节流 的传输层通信协议。数据大小无限制。 建立连接的过程需要 三次握手 。 断开连接的过程需要 四次挥手 。 使用TCP协议的通信双方分别为 客户端 和 服务器端 。 客户端负责向服务

    2024年01月23日
    浏览(58)
  • C++网络编程(一)本地socket通信

    本次内容简单描述C++网络通信中,采用socket连接客户端与服务器端的方法,以及过程中所涉及的函数概要与部分函数使用细节。记录本人C++网络学习的过程。 socket,即“插座”,在网络中译作中文“套接字”,应用于计算机网络建立起数据连接。基于TCP/IP协议进行通信,将本地的

    2024年02月15日
    浏览(43)
  • 【QT网络编程】实现UDP协议通信

    Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了 一种无需建立连接就可以发送封装的 IP 数据包的方法 。RFC 768 描述了 UDP。 UDP协议根据消息传送模式可以分为: 单播(Unicast)、组播(Multicast)和广播(

    2024年02月02日
    浏览(52)
  • 【Qt网络编程】实现TCP协议通信

    传输控制协议(TCP,Transmission Control Protocol)是 一种面向连接的、可靠的、基于字节流的传输层通信协议 ,由IETF的RFC 793 定义。 TCP建立连接前,需要进行三次握手,如下图所示: TCP断开连接前,需要进行四次挥手,如下图所示: Qt中提供了QTcpSocket类和QTcpServer类分别用于创

    2024年02月16日
    浏览(46)
  • 网络编程day2——基于TCP/IP协议的网络通信

            计算机S                                                 计算机C      创建socket对象                                   创建socket对象      准备通信地址(自己的ip(非公网ip))      准备通信地址                                     (计算

    2024年02月10日
    浏览(64)
  • Java网络编程之IP,端口号,通信协议(UDP,TCP)

    ① C/S :客户端/服务器 在用户本地需要下载安装客户端程序,在远程有一个服务器端程序。 优点:画面精美,用户体验好 缺点:用户需要下载更新 ② B/S :浏览器/服务器 只需要一个浏览器,用户通过指定网址访问对应的服务器。 优点:不需要开发客户端,只需要页面+服务

    2024年02月03日
    浏览(78)
  • UNIX 域协议(本地通信协议)

            Unix 域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务通信的一种方式。是进程间通信(IPC)的一种方式。         它提供了两类套接字:字节流套接字 SOCK_STREAM(有点像 TCP)和数据报套接字 SOCK_DGRAM(有点像 UDP)         UNIX 域数据报服

    2024年02月08日
    浏览(27)
  • 网络编程——深入理解TCP/IP协议——OSI模型和TCP/IP模型:构建网络通信的基石

    TCP/IP协议,即 传输控制协议/互联网协议 ,是一组用于在计算机网络中实现通信的协议。它由两个主要的协议组成:TCP(传输控制协议)和IP(互联网协议)。TCP负责确保数据的可靠传输,而IP则负责路由数据包以在网络中传递。TCP/IP协议簇还包含其他辅助协议,如UDP(用户数

    2024年02月14日
    浏览(53)
  • Unix 网络编程:Socket 状态图&编程参数

        Flags (9 bits) (aka Control bits) . Contains 9 1-bit flags NS (1 bit): ECN-nonce - concealment protection (experimental: see RFC 3540). CWR (1 bit): Congestion Window Reduced (CWR) flag is set by the sending host to indicate that it received a TCP segment with the ECE flag set and had responded in congestion control mechanism (added to header by RFC 31

    2024年02月02日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包