转自:https://blog.csdn.net/baidu_24553027/article/details/54912724

使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。

其主要流程如下:

 

代码实现如下:

客户端:

  1.  
    //client
  2.  
    #include<stdio.h>
  3.  
    #include<string.h>
  4.  
    #include<sys/types.h>
  5.  
    #include<sys/socket.h>
  6.  
    #include<sys/un.h>
  7.  
    #define UNIX_DOMAIN "/home/zhangmiaoling/test/socket/UNIX.domain"
  8.  
    int main(){
  9.  
    int connect_fd;
  10.  
    int ret;
  11.  
    char send_buff[1024];
  12.  
    int i;
  13.  
    static struct sockaddr_un srv_addr;
  14.  
    // creat unix socket
  15.  
    connect_fd=socket(PF_UNIX,SOCK_STREAM,0);
  16.  
    if(connect_fd<0){
  17.  
    perror("cannot creat socket");
  18.  
    return -1;
  19.  
    }
  20.  
    srv_addr.sun_family=AF_UNIX;
  21.  
    strcpy(srv_addr.sun_path,UNIX_DOMAIN);
  22.  
    //connect server
  23.  
    ret=connect(connect_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
  24.  
    if (ret<0){
  25.  
    perror("cannot connect server");
  26.  
    close(connect_fd);
  27.  
    return -1;
  28.  
    }
  29.  
    memset(send_buff,0,1024);
  30.  
    strcpy(send_buff,"message from client");
  31.  
    //send info server
  32.  
    write(connect_fd,send_buff,sizeof(send_buff));
  33.  
    close(connect_fd);
  34.  
    return 0;
  35.  
    }

服务器端:

  1.  
    //server
  2.  
    #include<stdio.h>
  3.  
    #include<sys/socket.h>
  4.  
    #include<sys/types.h>
  5.  
    #include<sys/un.h>
  6.  
    #define UNIX_DOMAIN "/home/zhangmiaoling/test/socket/UNIX.domain"
  7.  
     
  8.  
    int main(){
  9.  
     
  10.  
    socklen_t clt_addr_len;
  11.  
    int listen_fd;
  12.  
    int com_fd;
  13.  
    int ret;
  14.  
    int i;
  15.  
    static char rcv_buff[1024];
  16.  
    int len;
  17.  
    struct sockaddr_un clt_addr;
  18.  
    struct sockaddr_un srv_addr;
  19.  
    listen_fd=socket(AF_UNIX,SOCK_STREAM,0);
  20.  
    if(listen_fd<0){
  21.  
    perror("connect creat communication socket");
  22.  
    }
  23.  
    // set srv_addr param
  24.  
    srv_addr.sun_family=AF_UNIX;
  25.  
    strncpy(srv_addr.sun_path,UNIX_DOMAIN,sizeof(srv_addr.sun_path)-1);
  26.  
    unlink(UNIX_DOMAIN);
  27.  
    //bind sockfd&addr
  28.  
    ret=bind(listen_fd,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
  29.  
    if(ret<0){
  30.  
    perror("cannot bind server socket");
  31.  
    close(listen_fd);
  32.  
    unlink(UNIX_DOMAIN);
  33.  
    return -1;
  34.  
    }
  35.  
    //listen sockfd
  36.  
    ret=listen(listen_fd,1);
  37.  
    if(ret<0){
  38.  
    perror("cannot listen sockfd");
  39.  
    close(listen_fd);
  40.  
    unlink(UNIX_DOMAIN);
  41.  
    return -1;
  42.  
    }
  43.  
    //have connect requst use accept
  44.  
    len=sizeof(clt_addr);
  45.  
    com_fd=accept(listen_fd,(struct sockaddr*)&clt_addr,&len);
  46.  
    if(com_fd<0){
  47.  
    perror("cannot accept requst");
  48.  
    close(listen_fd);
  49.  
    unlink(UNIX_DOMAIN);
  50.  
    return -1;
  51.  
    }
  52.  
    //read and printf client send info
  53.  
    printf("\n******info********\n");
  54.  
    //for(i=0,i<4,i++){
  55.  
    for(i=0;i<4;i++){
  56.  
    memset(rcv_buff,0,1024);
  57.  
    int num = read(com_fd,rcv_buff,sizeof(rcv_buff));
  58.  
    printf("message from client %d : %s\n",num,rcv_buff);
  59.  
    }
  60.  
    close(com_fd);
  61.  
    close(listen_fd);
  62.  
    unlink(UNIX_DOMAIN);
  63.  
    return 0;
  64.  
     
  65.  
    }

一. 创建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进行本地进程间通信的更多相关文章

  1. linux系统下本地搭建git服务器

    linux系统下如何搭建本地git服务器,用于存放团队的开发代码,如下步骤: 1.先用一台服务器来安装git,安装好linux以后,在这里选用的是Ubuntu 14.04.然后配置静态IP:172.1 ...

  2. 【转】Linux系统下的ssh使用

    Linux系统下的ssh使用(依据个人经验总结)   对于linux运维工作者而言,使用ssh远程远程服务器是再熟悉不过的了!对于ssh的一些严格设置也关系到服务器的安全维护,今天在此,就本人工作中使 ...

  3. ZT Linux系统环境下的Socket编程详细解析

    Linux系统环境下的Socket编程详细解析 来自: http://blog.163.com/jiangh_1982/blog/static/121950520082881457775/ 什么是So ...

  4. linux系统下的权限知识梳理

    下面对linux系统下的有关权限操作命令进行了梳理总结,并配合简单实例进行说明.linux中除了常见的读(r).写(w).执行(x)权限以外,还有其他的一些特殊或隐藏权限,熟练掌握这些权限知识的使用, ...

  5. linux系统下修改文件夹目录权限

    linux系统下修改文件夹目录权限 文件夹权限问题 Linux.Fedora.Ubuntu修改文件.文件夹权限的方法差不多.很多人开始接触Linux时都很头痛Linux的文件权限问题.这里告诉大家如何 ...

  6. Linux系统下远程文件拷贝scp命令

    在Linux系统下,不同机器上实现文件拷贝 一.将本地文件拷贝到远程机器: scp /home/administrator/news.txt root@192.168.6.129:/etc/squid ...

  7. Linux系统下Redis安装(一)

    最近项目要使用Redis,特将这段时间将Redis的学习经验与大家分享,算是对这段时间学习成果的总结和技术提炼,不足之处还望大家批评指正. 项目背景: 有些很少改动的数据和经常使用的数据(例如系统中下 ...

  8. Linux系统下fd分配的方法

    最近几天在公司里写网络通讯的代码比较多,自然就会涉及到IO事件监测方法的问题.我惊奇的发现select轮训的方法在那里居然还大行其道.我告诉他们现在无论在Linux系统下,还是windows系统下,s ...

  9. 在Linux系统下安装大于mysql5.5版本的数据库

    linux下mysql 5.5的安装方法: 1.安装所需要系统库相关库文件      gcc等开发包,在安装linux系统的时候安装. 2.创建mysql安装目录 # mkdir -p /usr/lo ...

随机推荐

  1. Storm——Android SQLite数据库管理类库

    Storm是一个Android SQLite数据库管理类库,可以通过注解创建表和迁移数据库.它不是ORM框架.   特性: 1.通过@Annotations创建表: 2.通过@Annotations迁 ...

  2. Coolpy网络部署说明(宽带互联网)

    本文将介绍Coolpy第二种方案的网络部署方法.以方便大家学习如何让coolpy设备部署到相应的应用场景中.本例将以水星MW310R无线路由器作为演示路由器. 1.硬件连接部分: coolpy设备=& ...

  3. yii2上传七牛图片(超详细)

    前期准备 1.在七牛注册账号https://portal.qiniu.com/signup/choice 2.创建空间https://portal.qiniu.com/bucket(记住存储空间名称和 ...

  4. crc循环冗余检验

    CRC(Cyclic Redundancy Check):循环冗余检验.在链路层被广泛使用的检错技术. CRC原理: 1.发送端 1.1.在发送端先将数据分组,每组k个数据.假定要传送的数据是M. 1 ...

  5. HDU 2426 Interesting Housing Problem (最大权完美匹配)【KM】

    <题目链接> 题目大意: 学校里有n个学生和m个公寓房间,每个学生对一些房间有一些打分,如果分数为正,说明学生喜欢这个房间,若为0,对这个房间保持中立,若为负,则不喜欢这个房间.学生不会住 ...

  6. POJ1062昂贵的聘礼(经典) 枚举区间 +【Dijkstra】

    <题目链接>                   昂贵的聘礼 Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用1000 ...

  7. snmp 里面oid对应的信息 MIB

    系统参数(1.3.6.1.2.1.1) OID 描述 备注 请求方式 .1.3.6.1.2.1.1.1.0 获取系统基本信息 SysDesc GET .1.3.6.1.2.1.1.3.0 监控时间 s ...

  8. BeagleBone Black 从零到一 (2 MLO、U-Boot) 转

    文章原址:jexbat.com/categories/BeagleBone/ 什么是 U-Boot 熟悉嵌入式开发的应该都听过它,U-boot 就是启动系统前的一段引导程序,虽然是引导程序,但是功能非 ...

  9. 路由网关---zuul

    Zuul:Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架.Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门. 在微服务盛行的时代,客户端与系统之 ...

  10. Linux——awk命令解析

    awk简介 awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母.实际上 AWK 的确拥有自己的语言: AWK 程 ...