首页 > 其他分享 >本地套接字domain的使用

本地套接字domain的使用

时间:2023-12-02 10:22:06浏览次数:42  
标签:domain socket UNIX fd 本地 address 接字 include Socket

socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIX Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。UNIX Domain Socket是全双工的,API接口语义丰富,相比其它IPC机制有明显的优越性,目前已成为使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过UNIXDomain Socket通讯的。使用UNIX Domain Socket的过程和网络socket十分相似,也要先调用socket()创建一个socket文件描述符,address family指定为AF_UNIX,type可以选择SOCK_DGRAM或SOCK_STREAM,protocol参数仍然指定为0即可。UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。

服务端示例代码:

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

#define SOCKET_PATH "/tmp/local_socket"

int main() {
    int server_fd, new_socket;
    socklen_t addrlen;
    struct sockaddr_un address;

    // 创建套接字
    if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    address.sun_family = AF_UNIX;
    strncpy(address.sun_path, SOCKET_PATH, sizeof(address.sun_path) - 1);

    // 绑定套接字到指定路径
    if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) == -1) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 监听套接字
    if (listen(server_fd, 5) == -1) {
        perror("listen failed");
        exit(EXIT_FAILURE);
    }

    printf("Server waiting for connections...\n");

    // 接受连接
    addrlen = sizeof(address);
    if ((new_socket = accept(server_fd, (struct sockaddr*)&address, &addrlen)) == -1) {
        perror("accept failed");
        exit(EXIT_FAILURE);
    }

    // 读取客户端发送的数据
    char buffer[1024];
    ssize_t nbytes = read(new_socket, buffer, sizeof(buffer));
    if (nbytes > 0) {
        buffer[nbytes] = '\0';
        printf("Received message: %s\n", buffer);
    }

    // 关闭套接字
    close(new_socket);
    close(server_fd);
    unlink(SOCKET_PATH);

    return 0;
}

客户端示例代码:

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

#define SOCKET_PATH "/tmp/local_socket"

int main() {
    int client_fd;
    struct sockaddr_un serv_addr;

    // 创建套接字
    if ((client_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    serv_addr.sun_family = AF_UNIX;
    strncpy(serv_addr.sun_path, SOCKET_PATH, sizeof(serv_addr.sun_path) - 1);

    // 连接到服务器
    if (connect(client_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) {
        perror("connect failed");
        exit(EXIT_FAILURE);
    }

    // 发送消息到服务器
    const char* message = "Hello from client";
    ssize_t nbytes = send(client_fd, message, strlen(message), 0);
    if (nbytes == -1) {
        perror("send failed");
    } else {
        printf("Sent message to server: %s\n", message);
    }

    // 关闭套接字
    close(client_fd);

    return 0;
}

  

标签:domain,socket,UNIX,fd,本地,address,接字,include,Socket
From: https://www.cnblogs.com/TechNomad/p/17871311.html

相关文章

  • flask接受图像,并保存到本地
    当服务端接收到图像后,要保存图像到本地可以使用Python的io模块来辅助处理接收的图像数据。以下是对服务端代码的修改,使其能够接收图像并保存到本地fromflaskimportFlask,requestimportbase64importiofromPILimportImageapp=Flask(__name__)defprocess_image......
  • 使用Unity Localization插件进行项目本地化实战详解
    在使用Unity开发游戏的过程中,本地化是必不可少的。网络上也有很多的本地化工具,本次我介绍的是Unity官方提供的Localization插件,大家可以在PackageManager进行安装 一、语言配置,本地化表创建在ProjectSetting中找到Localization,(需要先创建这个LocalizationSetting文件)点击L......
  • 使用vagrant搭建本地centos/7
    一、环境搭建1、虚拟机注意:本机要先开启cpu虚拟化1.1、VirtualBox下载地址:Downloads–OracleVMVirtualBox注:修改安装地址,其他的都直接下一步1.2、虚拟机镜像vargrant地址:Install|Vagrant|HashiCorpDeveloper安装后重启电脑,验证是否安装完成 进入控制台,输......
  • python打包本地pip包需要注意哪些问题
    参考资料:https://packaging.python.org/tutorials/packaging-projects/提到Python的包管理器,大多数人都会想到pip和conda,其中又尤以pip简单好用。那么如果有一天你写了一个有用的项目,想要发布给公众,或者实现方便的安装,那么你可能就会想要自己去打包一个pip包。毕竟,......
  • Git本地仓库创建和一些基本概念
    Git本地仓库创建和一些基本概念1.使用gitinit命令创建本地仓库gitinit初始化一个仓库gitinitAA在AA文件夹里创建一个仓库2.仓库区和工作区.git文件夹为仓库区,类似于一个数据库存储着每一次提交的变化.git所在目录称为工作区,我们在这里创建项目,和其他文件3.......
  • 在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面通讯
    转载于在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面通讯-DCloud问答uni-app的web-view组件,支持加载远程网页,在app环境下,还支持加载本地HTML页面。在web-view加载页面中,会涉及wx、plus、uni等对象的使用。在小程序下使用wx的api,需要引入微信提供的https......
  • SFTP文件本地及远程创建,上传,下载,删除,获取脚本
    关键参数:sftp_route:远程路径local_route:本地路径(windows需要r解析)header:txt表头字段(列表方式)data:txt内容信息(列表嵌套列表方式)filename_success:是否创建success文件默认为falsefilename:文件名称(无需带后缀默认为txt文件) 注意:上传文件需要带文件名称下载只需要到文件路......
  • Python | 将本地文件上传到远程服务器
    在Python中,可以使用paramiko库来通过SSH进行文件的传输。首先,你需要安装paramiko库,可以使用以下命令进行安装:pipinstallparamiko然后,你可以使用以下Python脚本进行文件传输:此脚本使用SFTP协议进行文件传输。在SFTP的上下文中,你可以使用put方法将本地文件上传到远程服务器。import......
  • 本地Linux 服务器实现公网SFTP远程传输文件(小白教程)
    简单几步实现使用SFTP结合cpolar工具实现远程Linux服务器传输文件1.查看局域网IP地址检查Linux局域网IP地址,我们输入:ipaddress然后即可看到设备的局域网IP地址2.局域网测试连接我们打开连接工具,这里使用winSCP连接测试,协议选择SFTP,输入上面查看的ip地址,端口号默认......
  • Gitee - 基于 Git 的代码托管和研发协作平台本地代码同步教程
    什么是Gitee?一、Gitee的发展史。Gitee(码云)是开源中国于2013年推出的基于Git的代码托管平台、企业级研发效能平台,提供中国本土化的代码托管服务。二、个人对Gitee的理解Gitee跟Git有什么区别,个人认为一个是国内、一个是国外,但是两个的目的都是一样的,都是为了方便彼此更好的代......