linux 系统下使用socket进行本地进程间通信
转自:https://blog.csdn.net/baidu_24553027/article/details/54912724
使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。
其主要流程如下:
客户端:
- //client
- #include<stdio.h>
- #include<string.h>
- #include<sys/types.h>
- #include<sys/socket.h>
- #include<sys/un.h>
- #define UNIX_DOMAIN "/home/zhangmiaoling/test/socket/UNIX.domain"
- int main(){
- int connect_fd;
- int ret;
- char send_buff[1024];
- int i;
- static struct sockaddr_un srv_addr;
- // creat unix socket
- connect_fd=socket(PF_UNIX,SOCK_STREAM,0);
- if(connect_fd<0){
- perror("cannot creat socket");
- return -1;
- }
- srv_addr.sun_family=AF_UNIX;
- strcpy(srv_addr.sun_path,UNIX_DOMAIN);
- //connect server
- ret=connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
- if (ret<0){
- perror("cannot connect server");
- close(connect_fd);
- return -1;
- }
- memset(send_buff,0,1024);
- strcpy(send_buff,"message from client");
- //send info server
- write(connect_fd,send_buff,sizeof(send_buff));
- close(connect_fd);
- return 0;
- }
服务器端:
- //server
- #include<stdio.h>
- #include<sys/socket.h>
- #include<sys/types.h>
- #include<sys/un.h>
- #define UNIX_DOMAIN "/home/zhangmiaoling/test/socket/UNIX.domain"
- int main(){
- socklen_t clt_addr_len;
- int listen_fd;
- int com_fd;
- int ret;
- int i;
- static char rcv_buff[1024];
- int len;
- struct sockaddr_un clt_addr;
- struct sockaddr_un srv_addr;
- listen_fd=socket(AF_UNIX,SOCK_STREAM,0);
- if(listen_fd<0){
- perror("connect creat communication socket");
- }
- // set srv_addr param
- srv_addr.sun_family=AF_UNIX;
- strncpy(srv_addr.sun_path,UNIX_DOMAIN,sizeof(srv_addr.sun_path)-1);
- unlink(UNIX_DOMAIN);
- //bind sockfd&addr
- ret=bind(listen_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
- if(ret<0){
- perror("cannot bind server socket");
- close(listen_fd);
- unlink(UNIX_DOMAIN);
- return -1;
- }
- //listen sockfd
- ret=listen(listen_fd,1);
- if(ret<0){
- perror("cannot listen sockfd");
- close(listen_fd);
- unlink(UNIX_DOMAIN);
- return -1;
- }
- //have connect requst use accept
- len=sizeof(clt_addr);
- com_fd=accept(listen_fd,(struct sockaddr*)&clt_addr,&len);
- if(com_fd<0){
- perror("cannot accept requst");
- close(listen_fd);
- unlink(UNIX_DOMAIN);
- return -1;
- }
- //read and printf client send info
- printf("\n******info********\n");
- //for(i=0,i<4,i++){
- for(i=0;i<4;i++){
- memset(rcv_buff,0,1024);
- int num = read(com_fd,rcv_buff,sizeof(rcv_buff));
- printf("message from client %d : %s\n",num,rcv_buff);
- }
- close(com_fd);
- close(listen_fd);
- unlink(UNIX_DOMAIN);
- return 0;
- }
一. 创建socket
创建socket,类型为AF_LOCAL或AF_UNIX,表示用于进程通信:
调用函数socket(),其原型如下:
int socket(int domain, int type, int protocol);
参数:
domain:指定协议族,对于本地套接字来说,值必须设置为AF_UNIX枚举值;
type:指定套接字类型,可以被设置为SOCK_STREAM(流式套接字)活SOCK_DGRAM(数据报式套接字)
protocol:指定具体的协议,应被设置为0
返回值为生成的套接字描述符。
对于本地套接字来说,流式套接字(SOCK_STREAM)是一个有顺序的、可靠的双向字节流,相当于在本地进程之间建立起一条数据通道;数据报式套接字(SOCK_DGRAM)相当于单纯的发送消息,在进程通信过程中,理论上可能会有信息丢失、复制或者不按先后次序到达的情况,但由于其在本地通信,不通过外界网络,这些情况出现的概率很小。
二. 设置socket参数
SOCK_STREAM式本地套接字的通信双方均需要有本地地址,其中服务器端的本地地址需要明确指定,指定方法是使用struct sockaddr_un类型的变量
struct sockaddr_un{
sa_family_t sun_family; // AF_UNIX
char sun_path[UNIX_PATH_MAX]; // 路径名
}
三. 绑定
绑定要使用 bind 系统调用,其原形如下:
int bind(int socket, const struct sockaddr *address, size_t address_len);
参数
socket:服务端套接字描述符
address:需要绑定的服务端本地地址
address_len:本地地址的字节长度
四. 监听
服务器端套接字创建完毕并赋予本地地址值(名称,本例中为CAN_SERVICE)后,需要进行监听,等待客户端连接并处理请求,监听使用 listen 系统调用,接受客户端连接使用accept系统调用,它们的原形如下:
int listen(int socket, int backlog);
int accept(int socket, struct sockaddr *address, size_t *address_len);
参数
socket:表示服务器端的套接字描述符;
backlog 表示排队连接队列的长度(若有多个客户端同时连接,则需要进行排队);
address 表示当前连接客户端的本地地址,该参数为输出参数,是客户端传递过来的关于自身的信息;
address_len 表示当前连接客户端本地地址的字节长度,这个参数既是输入参数,又是输出参数。实现监听、接受和处理。
五. 连接
客户端需要socket系统调用connect()连接到服务端,其函数原型如下:
int connect(int socket, const struct sockaddr *address, size_t address_len);
参数
socket:客户端的套接字描述符
address:当前客户端的本地地址,是一个 struct sockaddr_un 类型的变量
address_len:表示本地地址的字节长度
五. 数据交互
无论客户端还是服务器,都要和对方进行数据上的交互。一个进程扮演客户端的角色,另外一个进程扮演服务器的角色,两个进程之间相互发送接收数据,这就是基于本地套接字的进程通信。
循环读取客户端发送的消息,当客户端没有发送数据时会阻塞直到有数据到来。如果想要多个连接并发处理,需要创建线程,将每个连接交给相应的线程并发处理。接收到数据后,进行相应的处理,将结果返回给客户端。发送和接收数据要使用 write 和 read 系统调用,它们的原形为:
int read(int socket, char *buffer, size_t len);
int write(int socket, char *buffer, size_t len);
linux 系统下使用socket进行本地进程间通信的更多相关文章
- linux系统下本地搭建git服务器
linux系统下如何搭建本地git服务器,用于存放团队的开发代码,如下步骤: 1.先用一台服务器来安装git,安装好linux以后,在这里选用的是Ubuntu 14.04.然后配置静态IP:172.1 ...
- 【转】Linux系统下的ssh使用
Linux系统下的ssh使用(依据个人经验总结) 对于linux运维工作者而言,使用ssh远程远程服务器是再熟悉不过的了!对于ssh的一些严格设置也关系到服务器的安全维护,今天在此,就本人工作中使 ...
- ZT Linux系统环境下的Socket编程详细解析
Linux系统环境下的Socket编程详细解析 来自: http://blog.163.com/jiangh_1982/blog/static/121950520082881457775/ 什么是So ...
- linux系统下的权限知识梳理
下面对linux系统下的有关权限操作命令进行了梳理总结,并配合简单实例进行说明.linux中除了常见的读(r).写(w).执行(x)权限以外,还有其他的一些特殊或隐藏权限,熟练掌握这些权限知识的使用, ...
- linux系统下修改文件夹目录权限
linux系统下修改文件夹目录权限 文件夹权限问题 Linux.Fedora.Ubuntu修改文件.文件夹权限的方法差不多.很多人开始接触Linux时都很头痛Linux的文件权限问题.这里告诉大家如何 ...
- Linux系统下远程文件拷贝scp命令
在Linux系统下,不同机器上实现文件拷贝 一.将本地文件拷贝到远程机器: scp /home/administrator/news.txt root@192.168.6.129:/etc/squid ...
- Linux系统下Redis安装(一)
最近项目要使用Redis,特将这段时间将Redis的学习经验与大家分享,算是对这段时间学习成果的总结和技术提炼,不足之处还望大家批评指正. 项目背景: 有些很少改动的数据和经常使用的数据(例如系统中下 ...
- Linux系统下fd分配的方法
最近几天在公司里写网络通讯的代码比较多,自然就会涉及到IO事件监测方法的问题.我惊奇的发现select轮训的方法在那里居然还大行其道.我告诉他们现在无论在Linux系统下,还是windows系统下,s ...
- 在Linux系统下安装大于mysql5.5版本的数据库
linux下mysql 5.5的安装方法: 1.安装所需要系统库相关库文件 gcc等开发包,在安装linux系统的时候安装. 2.创建mysql安装目录 # mkdir -p /usr/lo ...
随机推荐
- JMeter性能测试,验证请求数据的准确性(wc命令)
wc: 该命令统计给定文件中的字节数.字数.行数.如果没有给出文件名,则从标准输入读取. wc同时也给出所有指定文件的总统计数.字是由空格字符区分开的最大字符串. - c 统计字节数. - l 统计行 ...
- hive中使用union出现异常数据
select * from tbl where id=2 union select * from tbl where id =1 如果hive使用union这么查询的时候,我们会发现数据变乱了. 解决 ...
- XXX系统项目目标文档课堂讨论
XXXX重大技术征集系统 1.讨论结果: 2.项目目标文档 A目标: 1. 实现普通用户在线需求填报,个人信息管理,需求结果查看. 2. 实现审核员用户的需求审核,需求查看浏览和生成图表结果. 3. ...
- 20165235 实验一 Java开发环境的熟悉
20165235 实验一 Java开发环境的熟悉 课程:JAVA程序设计 姓名:祁瑛 学号:20165235 指导老师:娄嘉鹏 实验日期: 2018.4.2 实验内容:java开发环境的熟悉 一,实验 ...
- webapp用户身份认证方案 JSON WEB TOKEN 实现
webapp用户身份认证方案 JSON WEB TOKEN 实现Deme示例,Java版 本项目依赖于下面jar包: nimbus-jose-jwt-4.13.1.jar (一款开源的成熟的JSON ...
- hdu 1237 简单计算器 (表达式求值)【stack】
<题目链接> 题目大意: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. Input测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符, ...
- Java常用的九种排序方法及代码实现
package com.algorithm.Demo; import java.util.ArrayList; import java.util.Arrays; import java.util.Li ...
- Java内存管理-掌握类加载器的核心源码和设计模式(六)
勿在流沙筑高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇文章介绍了类加载器分类以及类加载器的双亲委派模型,让我们能够从整体上对类加载器有 ...
- 读取XML文件内容
myeclipse中类的格式 上面中的RunMain.java为程序执行的入口,JdbcUtil.java为实体类,XmlDocumentUtil.java执行解释xml文件与获取里面的属性,程序所需 ...
- Java NIO- 最好文档
http://www.cnblogs.com/puyangsky/p/5840873.html 1 背景介绍 在上一篇文章中我们介绍了Java基本IO,也就是阻塞式IO(BIO),在JDK1.4版本后 ...