Linux本地套接字

2023-11-10

LINUX和UNIX都拥有一个非常实用的工具--UNIX套接字,或称为本地套接字,它可以被用在进程间通讯(IPC)当中。UNIX套接字的运转机制和Internet套接字类似,主要的区别UNIX套接字只能用在一台计算机中,而Internet套接字则可以在不同的计算机之间使用。UNIX套接字定址的方式是作为本地文件系统里的一个文件。

你可能会奇怪为什么要使用UNIX套接字而不使用常规的Internet套接字呢?或许最大的原因就是安全和速度了。无论何时,当你打开任何Internet套接字的时候,你可能就帮远程的黑客打开了入侵之门。



创建
使用套接字函数socket创建,不过传递的参数与网络套接字不同。域参数应该是PF_LOCAL或者PF_UNIX,而不能用PF_INET之类。本地套接字的通讯类型应该是SOCK_STREAM或SOCK_DGRAM,协议为默认协议。例如:
 int sockfd;
 sockfd = socket(PF_LOCAL, SOCK_STREAM, 0);

绑定
创建了套接字后,还必须进行绑定才能使用。不同于网络套接字的绑定,本地套接字的绑定的是struct sockaddr_un结构。struct sockaddr_un结构有两个参数:sun_family、sun_path。sun_family只能是AF_LOCAL或AF_UNIX,而sun_path是本地文件的路径。通常将文件放在/tmp目录下。例如:

 struct sockaddr_un sun;
 sun.sun_family = AF_LOCAL;
 strcpy(sun.sun_path, filepath);
 bind(sockfd, (struct sockaddr*)&sun, sizeof(sun));

监听
本地套接字的监听、接受连接操作与网络套接字类似。

连接
连接到一个正在监听的套接字之前,同样需要填充struct sockaddr_un结构,然后调用connect函数。

连接建立成功后,我们就可以像使用网络套接字一样进行发送和接受操作了。

服务器端代码


    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <sys/un.h>
    #include <unistd.h>
    #include <stdlib.h>

    int main (int argc, char *argv[])
    {
            int server_sockfd, client_sockfd;
            int server_len, client_len;
            struct sockaddr_un server_address;      /*声明一个UNIX域套接字结构*/
            struct sockaddr_un client_address;
            int i, bytes;
            char ch_send, ch_recv;

            unlink ("server_socket");       /*删除原有server_socket对象*/

            /*创建 socket, 通信协议为AF_UNIX, SCK_STREAM 数据方式*/
            server_sockfd = socket (AF_UNIX, SOCK_STREAM, 0);

            /*配置服务器信息(通信协议)*/
            server_address.sun_family = AF_UNIX;

            /*配置服务器信息(socket 对象)*/
            strcpy (server_address.sun_path, "server_socket");

            /*配置服务器信息(服务器地址长度)*/
            server_len = sizeof (server_address);

            /*绑定 socket 对象*/
            bind (server_sockfd, (struct sockaddr *)&server_address, server_len);

            /*监听网络,队列数为5*/
            listen (server_sockfd, 5);

            printf ("Server is waiting for client connect...\n");

            client_len = sizeof (client_address);

            /*接受客户端请求; 第2个参数用来存储客户端地址; 第3个参数用来存储客户端地址的大小*/
            /*建立(返回)一个到客户端的文件描述符,用以对客户端的读写操作*/
            client_sockfd = accept (server_sockfd, (struct sockaddr *)&server_address, (socklen_t *)&client_len);
            if (client_sockfd == -1) {
                    perror ("accept");
                    exit (EXIT_FAILURE);
            }

            printf ("The server is waiting for client data...\n");

            for (i = 0, ch_send = '1'; i < 5; i++, ch_send++) {
                    if ((bytes = read (client_sockfd, &ch_recv, 1)) == -1) {
                            perror ("read");
                            exit (EXIT_FAILURE);
                    }

                    printf ("The character receiver from client is %c\n", ch_recv);

                    sleep (1);

                    if ((bytes = write (client_sockfd, &ch_send, 1)) == -1) {
                            perror ("read");
                            exit (EXIT_FAILURE);
                    }
            }

                    close (client_sockfd);
                    unlink ("server socket");
    }

客户端代码

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <sys/un.h>
    #include <unistd.h>
    #include <stdlib.h>

    int main (int argc, char *argv[])
    {
        struct sockaddr_un address;
        int sockfd;
        int len;
        int i, bytes;
        int result;
        char ch_recv, ch_send;

        /*创建socket,AF_UNIX通信协议,SOCK_STREAM数据方式*/
        if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
                perror ("socket");
                exit (EXIT_FAILURE);
        }

        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, ch_send = 'A'; i < 5; i++, ch_send++) {
            if ((bytes = write(sockfd, &ch_send, 1)) == -1) { /*发消息给服务器*/
                perror ("write");
                exit (EXIT_FAILURE);
            }

            sleep (2);    /*休息二秒钟再发一次*/

            if ((bytes = 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);
    }

如果服务器和客户端依次运行,可以在两边看到输出:
服务器端
 ./sock_local_server
Server is waiting for client connect...
The server is waiting for client data...
The character receiver from client is A
The character receiver from client is B
The character receiver from client is C
The character receiver from client is D
The character receiver from client is E
客户端
./sock_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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux本地套接字 的相关文章

  • idea工具基础配置(Mac)

    用于个人在初次使用idea时 做一些基础配置 便于后续快速开发 此文章不涉及快捷键设置 若需要快捷键设置可查看其他链接 idea Mac 快捷方式设置 快捷键改为eclipse 1 idea背景颜色 intelliJ IDEA gt pre
  • (每日一练)MATLAB数据拟合

    今天就的学习内容是数据拟合 数据拟合也称为曲线拟合 是一种把现有数据透过数学方法来代入一条数式的表示方式 科学和工程问题可以通过诸如采样 实验等方法获得若干离散的数据 根据这些数据 我们往往希望得到一个连续的函数 也就是曲线 或者更加密集的
  • SpringMVC学习笔记

    springMVC简单入门 快速搭建 pom xml依赖
  • JQuery DOM

    操作文本 常用方法 代码实现 div 我是div div
  • 用Python赚钱的4个大招,女程序员做副业躺赚

    关于穷 去年有了一个更学术的说法 隐形贫困人口 就是因为有太多 种草达人 让我们为了物质生活超前消费 再加上不理财的话 那简直是雪上加霜 看到知乎上面最近有一个很火的问题 90后的你 现在拥有多少存款 你会看到人生百态 有人父母双亡 白手起
  • Docker : Docker镜像的分层结构

    1 美图 2 概述 3 base镜像 base 镜像简单来说就是不依赖其他任何镜像 完全从0开始建起 其他镜像都是建立在他的之上 可以比喻为大楼的地基 docker镜像的鼻祖 base 镜像有两层含义 不依赖其他镜像 从 scratch 构
  • Github 如何设置 master 为默认分支

    起因 github 新版本上线之后 原默认分支为 master 现在统一改为了 main 我不禁产生疑问 为什么要改呢 原因大概是漂亮国农奴历史遗留问题导致的 master 奴隶主 slaver 奴隶 解决方法 我们已经习惯以 master
  • 算法:优先队列-理论

    目录 优先队列 我们平时比较常见的优先队列的场景有什么 优先队列的实现机制 java的优先队列是怎么实现的 优先队列 我们先回忆一下什么是队列 队列 一种先进先出的数据结构 主要关注点在于先入的元素
  • 【初级计量经济学】内生性问题——工具变量法(Stata实现)

    目录 1 数据来源以及变量详目 1 1变量一览表 1 2数据描述性统计 2 模型设定以及初步回归 2 1 OLS 模型 2 2 回归结果 2 3 回归结果分析 内生性问题校正 1工具变量法 2 两阶段最小二乘 3 豪斯曼检验 stata手工
  • 智能机器人用什么语言编程

    智能机器人用什么语言编程 对于很多家长们来说 他们的任务之一就是培养孩子的学习 很多的家长在培养孩子的学习方面可以说是十分的重视的 会给孩子选择一些能够有利于孩子成长的课程 就拿现在很多的家长想要孩子去学习机器人编程的课程来说 有的家长对于
  • servlet / jsp 学习——java,关系,区别,核心概念,代码例子

    互联网三大基石 HTTP HyperText Transfer Protocol 传输数据 URL Uniform Resource Locator 定位数据 HTML HyperText Markup Language 显示数据 serv
  • 类的构造函数和析构函数

    1 把对象的初始化工作放在构造函数中 把清除工作放在析构函数中 当对象被创建时 构造函数被自动执行 当对象消亡时 析构函数被自动执行 这下就不用担心忘了对象的初始化和清除工作 2 构造函数 析构函数与类同名 由于析构函数的目的与构造函数的相
  • CAD——MV视口与图层

    CAD MV视口与图层 MV视口 MV 空格 CAD MV视口锁定比例 Z S 1 nXP 图层 LA 空格 MV视口 MV 空格 MS 空格 表示进入MV视口空间 PS 空格 表示退出MV视口空间 操作 打开布局 gt MV 空格 gt

随机推荐

  • Flask 实现分页展示数据(简单套路)

    简单方法套路 套用模板 定义宏 在templates里新建一个 macros html 代码如下 macro pagination widget pagination endpoint ul class pagination ul
  • golang开发的准备 - gvm(go版本管理软件)的使用

    概述 gvm软件用于go版本的管理 主要的功能为go版本的查看 下载安装和切换 一 go版本的查看 gvm listall 命令用于查看可以下载安装的go版本 shane ubuntu gvm binscripts gvm listall
  • java Map集合的使用

    Map集合的使用 Map的特点 Map接口的常用实现类 Map集合的常用方法的使用 1 添加map集合元素 2 删除map集合元素 3 替换map集合元素 4 集合中是否包含指定的key和value 5 分别获取map集合中所有的key和v
  • Python中CV2及PIL库无法安装解决方式

    ERROR Could not find a version that satisfies the requirement cv2 from versions none ERROR No matching distribution foun
  • 关于DDOS的几个误区,你知道几个?

    在竞争激烈的互联网领域 总有一些组织和个人利用DDoS攻击进行破坏 从而达到自己的目的 对于DDoS攻击 大部分人的认知来源于新闻报道 新闻报道这种方式在普及DDoS危害性的同时 也会不自觉地引入一些误区 下面小墨就带大家来看看关于DDoS
  • Git常用操作总结,经常遇到但是记不住

    今天分享一些我平时在使用git时经常会遇到的几个问题 由于命令一直记不住 每次都得去搜索贼麻烦 所以今天想着整理一下分享出来 希望能帮助到也经常遇到这些问题的你 Git remote 使用总结 使用场景 新建一个git仓库并与远程关联 初始
  • 纯css画三角形

    思路 用border实现 lt html lang en gt lt head gt lt meta charset UTF 8 gt lt meta name viewport content width device width ini
  • 数学形态学滤波学习

    一 概述 数学形态学是建立在集合论基础上了一门学科 具体在图像处理领域 它把形态学和数学中的集合论结合起来 描述二值或灰度图像中的形态特征 来达到图形处理的目的 形态学主要是通过结构元素和图像的相互作用对图像进行拓补变换从而获得图像结构信息
  • 常用的概率分布:伯努利分布、二项分布、多项式分布、高斯分布、指数分布、拉普拉斯分布和Dirac-delta分布

    伯努利分布 Bernoulli distribution 伯努利分布 单个二值随机变量的分布 由单个参数 0 1 控制 例 抛硬币 正面朝上的概率 二项式分布 binomial distrubution 二项式分布 在n次试验中事件A恰好发
  • Android AIDL示例-RemoteCallbackList添加移除监听

    前言 AIDL是一个缩写 全称是Android Interface Definition Language 也就是Android接口定义语言 它是用来实现进程间通讯的 本文使用AIDL写一个小demo来实现夸进程间通讯 本文接着这一篇文章写
  • Git管理工具对比(GitBash、EGit、SourceTree)

    Git管理工具对比 GitBash EGit SourceTree GitBash是采用命令行的方式对版本进行管理 功能最为灵活强大 但是由于需要手动输入希望修改的文件名 所以相对繁琐 EGit是Eclipse的Git插件 最为纠结的一个软
  • 小乌龟Tortoisegit官方汉化包 中文语言安装

    进入小乌龟官网的Download界面下拉在Language中选择中文语言包简体 https tortoisegit org download 下载后直接双击 一步到位安装好 不用管安装路径 在桌面右键点击Tortoisegit选择Setti
  • 如何快速建立一个优秀的账号体系

    在2014年下半年开始 只支持第三方账号登陆的应用在提交苹果的appstore审核的时候被拒绝 拒信如下 If we chose to log in with 微信 we were required toinstall 微信 before
  • org.hibernate.UnknownEntityTypeException: Unable to locate persister:

    springboot2 0 当把Application放到其他包里面时 会出现标题的异常 针对此异常的解决办法是 增加jpa的配置类 使其能扫描到所有的bean package com bmSystem common sys config
  • 微信公众平台错误代码40164的解决方案

    获取微信公众号授权失败 请稍后重试 公众平台返回原始数据为 错误代码 40164 错误信息 invalid ip not in whitelist hint 59FKqA0797e514 错误解释 调用接口的IP地址不在白名单中 请在接口I
  • 车道线检测

    3D车道线单目检测方法 ONCE 3DLanes GitHub once 3dlanes once 3dlanes benchmark 斑马线 检测 上海交大 CDNet 基于YOLOv5改进的 人行道 斑马线和汽车过线行为检测 jacke
  • 详解vue中的v-model

    序 v model是v bind和v on input的结合 即监听了表单的input事件 然后修改value属性对应的值 一 vue单文件中使用v model 众所周知 当我们使用v bind绑定prop时 数据流的流向是从model层流
  • Centos7安装Redis并设置开机自启动图文详解

    1 下载redis wget http download redis io releases redis 6 0 0 tar gz 如果提示没有wget使用如下命令 yum y install wget 2 安装 解压 tar zxvf r
  • 【ES】Elasticsearch Java Rest Client (Document APIs)官方文档中文翻译

    这里写目录标题 一 文档APIs 1 单文档 API Index API Get API Get Source API Exists API Delete API Update API Term Vectors API 2 多文档 API
  • Linux本地套接字

    LINUX和UNIX都拥有一个非常实用的工具 UNIX套接字 或称为本地套接字 它可以被用在进程间通讯 IPC 当中 UNIX套接字的运转机制和Internet套接字类似 主要的区别UNIX套接字只能用在一台计算机中 而Internet套接