Unix Domain Socket 域套接字实现
主要注意流程:
STREAM SOCKET:
Server : socket() ---> bind() ---> listen() ---> accept()
Client: scoket() ---> connect()
参考文章一篇就够: http://troydhanson.github.io/misc/Unix_domain_sockets.html
自己写的 一个 Server 和 一个Client:
//Server
//
// unix_domain_server.c
// UnixDomainServer
//
// Created by gtliu on 7/11/13.
// Copyright (c) 2013 GT. All rights reserved.
//#include "MITLogModule.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stddef.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>#define FUNC_FAIL -1
#define FUNC_SUCCESS 0
#define SOCKADDR_UN_SUN_PATH_MAX_LEN 103 // 104 - 1
#define SER_ACCEPT_CON_NUM 1/*** Create a server endpoint of a connection.** @param scok_path: the unix domain socket path* @return return the file descirption if all ok, <0 on err*/
int create_serv_listen(const char *sock_path)
{size_t path_len = strlen(sock_path);if (path_len == 0) {MITLogWrite(MITLOG_LEVEL_ERROR, "socket path can't be empty");return FUNC_FAIL;} else if (path_len > SOCKADDR_UN_SUN_PATH_MAX_LEN) {MITLogWrite(MITLOG_LEVEL_ERROR, "socket path length must less than%d", SOCKADDR_UN_SUN_PATH_MAX_LEN);return FUNC_FAIL;}int fd = 0, size = 0;struct sockaddr_un server_un;memset(&server_un, 0, sizeof(server_un));server_un.sun_family = AF_UNIX;strncpy(server_un.sun_path, sock_path, sizeof(server_un.sun_path) - 1);if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {MITLogWrite(MITLOG_LEVEL_ERROR, "socket() faild:%s", strerror(errno));return FUNC_FAIL;}/* in case it already exists */unlink(sock_path);size = offsetof(struct sockaddr_un, sun_path) + strlen(server_un.sun_path);if (bind(fd, (struct sockaddr *)&server_un, size) < 0) {MITLogWrite(MITLOG_LEVEL_ERROR, "bind() failed:%s", strerror(errno));close(fd);return FUNC_FAIL;}if (listen(fd, 0) < 0) {MITLogWrite(MITLOG_LEVEL_ERROR, "listen() failed:%s", strerror(errno));close(fd);return FUNC_FAIL;}return fd;
}/*** Accept a client's connection and return the relative file descriptor.** @param listen_fd: the server socket file descriptor* @return return the file descirption if all ok, <0 on err*/
int serv_accept(int listen_fd)
{int child_fd = 0, len = 0;struct sockaddr_un income_un;len = sizeof(income_un);if ((child_fd = accept(listen_fd, (struct sockaddr *)&income_un, &len)) < 0) {MITLogWrite(MITLOG_LEVEL_ERROR, "accept() failed:%s", strerror(errno));/* often errno=EINTR, if signal caught */return FUNC_FAIL;}return child_fd;
}int main(int argc, const char * argv[])
{MITLogOpen("unix_domain_server");char *sock_path = "/tmp/domain_socket_one";if (argc > 1) {sock_path = (char *) argv[1];}MITLogWrite(MITLOG_LEVEL_COMMON, "Starting the server...");int listen_fd = create_serv_listen(sock_path);if (listen_fd == FUNC_FAIL) {return FUNC_FAIL;}MITLogWrite(MITLOG_LEVEL_COMMON, "Wait for the client... listen_fd:%d", listen_fd);int child_fd = serv_accept(listen_fd);if (child_fd == FUNC_FAIL) {close(listen_fd);return FUNC_FAIL;}char recv_buffer[1024] = {0};while (1) {MITLogWrite(MITLOG_LEVEL_COMMON, "Wait for the message...");if(read(child_fd, recv_buffer, sizeof(recv_buffer) - 1) > 0) {printf("Recieve message:%s\n", recv_buffer);}sleep(2);} MITLogClose();return 0;
}
//Client
//
// main.c
// UnixDomainClient
//
// Created by gtliu on 7/11/13.
// Copyright (c) 2013 GT. All rights reserved.
//#include "MITLogModule.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stddef.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>#define FUNC_FAIL -1
#define FUNC_SUCCESS 0
#define SOCKADDR_UN_SUN_PATH_MAX_LEN 103 // 104 - 1
#define SER_ACCEPT_CON_NUM 1/*** Create a server endpoint of a connection.** @param scok_path: the unix domain socket path* @return return the file descirption if all ok, <0 on err*/
int client_connection(const char *sock_path)
{size_t path_len = strlen(sock_path);if (path_len == 0) {MITLogWrite(MITLOG_LEVEL_ERROR, "socket path can't be empty");return FUNC_FAIL;} else if (path_len > SOCKADDR_UN_SUN_PATH_MAX_LEN) {MITLogWrite(MITLOG_LEVEL_ERROR, "socket path length must less than%d", SOCKADDR_UN_SUN_PATH_MAX_LEN);return FUNC_FAIL;}int fd = 0, len = 0;if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {MITLogWrite(MITLOG_LEVEL_ERROR, "socket() faild:%s", strerror(errno));return FUNC_FAIL;}struct sockaddr_un client_un;memset(&client_un, 0, sizeof(client_un));client_un.sun_family = AF_UNIX;strncpy(client_un.sun_path, sock_path, sizeof(client_un.sun_path) - 1);len = offsetof(struct sockaddr_un, sun_path) + strlen(client_un.sun_path);if ((connect(fd, (struct sockaddr *)&client_un, len)) < 0) {MITLogWrite(MITLOG_LEVEL_ERROR, "connect() failed:%s", strerror(errno));close(fd);return FUNC_FAIL;}return fd;
}int main(int argc, const char * argv[])
{MITLogOpen("unix_domain_client");char *sock_path = "/tmp/domain_socket_one";if (argc > 1) {sock_path = (char *) argv[1];}MITLogWrite(MITLOG_LEVEL_COMMON, "Starting the client...");int client_fd = client_connection(sock_path);if (client_fd == FUNC_FAIL) {return FUNC_FAIL;}for (int i=1; i < 100; ++i) {MITLogWrite(MITLOG_LEVEL_COMMON, "Send message to server...");char msg[256] = {0};sprintf(msg, "client message :%d", i);if(write(client_fd, msg, strlen(msg)) > 0) {MITLogWrite(MITLOG_LEVEL_COMMON, "Send message :%d success", i);}sleep(2);}MITLogClose();return 0;
}
Unix Domain Socket 域套接字实现相关推荐
- 【技术应用】java基于UNIX域套接字(unix domain socket)连接mysql数据库
前言 Unix domain socket 又叫 IPC(inter-process communication 进程间通信)socket,用于实现同一主机上的进程间通信. socket 原本是为网络 ...
- 【socket】 unix域套接字(socketpair )通信|socketpair和pipe的区别|进程间通信-Unix domain socket
目录 unix域套接字(socketpair )通信|socketpair和pipe的区别 socketpair机制 描述 原理 socketpair和pipe的区别 进程间通信-Unix domai ...
- UNIX Domain Socket(UDS)是什么?同一台主机间进程间通信
文章目录 概述 流程介绍 概述 Linux下进程通讯方式有很多,比较典型的有套接字,平时比较常用的套接字是基于TCP/IP协议的,适用于两台不同主机上两个进程间通信, 通信之前需要指定IP地址. 但是 ...
- Unix domain socket 简介(进程间通信,进程通信)
Unix domain socket 又叫 IPC(inter-process communication 进程间通信) socket,用于实现同一主机上的进程间通信.socket 原本是为网络通讯设 ...
- unix domain socket 浅析
unix domain socket unix domain socket 是在socket架构上发展起来的用于同一台主机的进程间通讯(IPC: Inter-Process Communication ...
- 网络协议之:socket协议详解之Unix domain Socket
文章目录 简介 什么是Unix domain Socket 使用socat来创建Unix Domain Sockets 使用ss命令来查看Unix domain Socket 使用nc连接到Unix ...
- unix网络编程之UNIX Domain Socket IPC (sockaddr_un )
socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通过loop ...
- Unix domain socket IPC
UNIX Domain socket 虽然网络socket也可用于同一台主机的进程间通讯(通过lo地址127.0.0.1),但是unix domain socket用于IPC更有效率:不需要经过网络协 ...
- 网络协议之socket协议详解之Unix domain Socket
简介 之前的文章我们讲到了Socket中的Stream Socket和Datagram Socket,和有连接的Stream Socket不同,Datagram Socket是无连接的.有连接的Str ...
最新文章
- 用surfaceView实现高性能动画
- Ansi与Unicode及慎用W2A等
- 团队项目改进与详细设计
- HTMLTestRunner修改Python3的版本
- [c#] HttpContext.Cache和AppFabric的性能对比
- 在 Windows 7 中安装和使用Windows XP Mode
- Tinymce4 中Ajax多次加载时,会出现菜单在第二次进入时,显示的下拉菜单在左上角...
- C专家编程 第1章 C:穿越时空的迷雾 1.1 C语言的史前阶段
- 安装服务器系统驱动加载不成功,安装windows server系统提示“无法在此驱动器上安装windows”的解决办法...
- 软件开发的里程碑简单概念
- 对公司的建议_工作总结
- Live555实时视频流应用总结
- 什么?HomeKit、米家、Aqara等生态也能通过智汀与天猫精灵生态联动?
- 天神娱乐:因资金状况紧张 未能清偿部分到期债务
- 线上发版如何做到分批发的?详解蓝绿部署,滚动升级,A/B 测试,灰度发布/金丝雀发布
- keyberos认证问题导致GSS initiate failed
- linux mysql 服务停止不了_Linux服务器mysql数据库自动停止的解决方法
- A段架构师_隽语集(IT+設計思考_2001)
- hyperledger/cello安装和使用
- android智能家居wifi原理图,WiFi模块为你讲解WiFi插座原理