返回顶部
首页 > 资讯 > 操作系统 >Linux进程间通信中如何使用流套接字
  • 183
分享到

Linux进程间通信中如何使用流套接字

2023-06-09 15:06:20 183人浏览 薄情痞子
摘要

小编给大家分享一下linux进程间通信中如何使用流套接字,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!进程间的通信,所通信的进程都是在同一台计算机上的,而使用So

小编给大家分享一下linux进程间通信中如何使用流套接字,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

进程间的通信,所通信的进程都是在同一台计算机上的,而使用Socket进行通信的进程可以是同一台计算机的进程,也是可以是通过网络连接起来的不同计算机上的进程。通常我们使用socket进行网络编程,这里将会简单地讲述如何使用socket进行简单的网络编程

一、什么是socket

socket,即套接字是一种通信机制,凭借这种机制,客户/服务器(即要进行通信的进程)系统的开发工作既可以在本地单机上进行,也可以跨网络进行。也就是说它可以让不在同一台计算机但通过网络连接计算机上的进程进行通信。也因为这样,套接字明确地将客户端和服务器区分开来。

二、套接字的属性

套接字的特性由3个属性确定,它们分别是:域、类型和协议。

1、套接字的域

它指定套接字通信中使用的网络介质,最常见的套接字域是AF_INET,它指的是Internet网络。当客户使用套接字进行跨网络的连接时,它就需要用到服务器计算机的IP地址和端口来指定一台联网机器上的某个特定服务,所以在使用socket作为通信的终点,服务器应用程序必须在开始通信之前绑定一个端口,服务器在指定的端口等待客户的连接。另一个域AF_UNIX表示UNIX文件系统,它就是文件输入/输出,而它的地址就是文件名。

2、套接字类型

因特网提供了两种通信机制:流(stream)和数据报(datagram),因而套接字的类型也就分为流套接字和数据报套接字。这里主要讲流套接字。

流套接字由类型SOCK_STREAM指定,它们是在AF_INET域中通过tcp/IP连接实现,同时也是AF_UNIX中常用的套接字类型。流套接字提供的是一个有序、可靠、双向字节流的连接,因此发送的数据可以确保不会丢失、重复或乱序到达,而且它还有一定的出错后重新发送的机制。

与流套接字相对的是由类型SOCK_DGRAM指定的数据报套接字,它不需要建立连接和维持一个连接,它们在AF_INET中通常是通过UDP/IP协议实现的。它对可以发送的数据的长度有限制,数据报作为一个单独的网络消息被传输,它可能会丢失、复制或错乱到达,UDP不是一个可靠的协议,但是它的速度比较高,因为它并一需要总是要建立和维持一个连接。

3、套接字协议

只要底层的传输机制允许不止一个协议来提供要求的套接字类型,我们就可以为套接字选择一个特定的协议。通常只需要使用默认值。

三、套接字地址

每个套接字都有其自己的地址格式,对于AF_UNIX域套接字来说,它的地址由结构sockaddr_un来描述,该结构定义在头文件sys/un.h中,它的定义如下:

struct sockaddr_un{   sa_family_t sun_family;//AF_UNIX,它是一个短整型   char    sum_path[];//路径名 };

对于AF_INET域套接字来说,它的地址结构由sockaddr_in来描述,它至少包括以下几个成员:

struct sockaddr_in{   short int      sin_family;//AF_INET   unsigned short int  sin_port;//端口号   struct in_addr    sin_addr;//IP地址 };

而in_addr被定义为:

struct in_addr{   unsigned long int s_addr; };

四、基于流套接字的客户/服务器的工作流程

使用socket进行进程通信的进程采用的客户/服务器系统是如何工作的呢?

1、服务器端

首先服务器应用程序用系统调用socket来创建一个套接安,它是系统分配给该服务器进程的类似文件描述符的资源,它不能与其他的进程共享。

接下来,服务器进程会给套接字起个名字,我们使用系统调用bind来给套接字命名。然后服务器进程就开始等待客户连接到这个套接字。

然后,系统调用listen来创建一个队列并将其用于存放来自客户的进入连接。

最后,服务器通过系统调用accept来接受客户的连接。它会创建一个与原有的命名套接不同的新套接字,这个套接字只用于与这个特定客户端进行通信,而命名套接字(即原先的套接字)则被保留下来继续处理来自其他客户的连接。

2、客户端

基于socket的客户端比服务器端简单,同样,客户应用程序首先调用socket来创建一个未命名的套接字,然后将服务器的命名套接字作为一个地址来调用connect与服务器建立连接。

一旦连接建立,我们就可以像使用底层的文件描述符那样用套接字来实现双向数据的通信。

五、流式socket的接口及作用

socket的接口函数声明在头文件sys/types.h和sys/socket.h中。

1、创建套接字——socket系统调用

该函数用来创建一个套接字,并返回一个描述符,该描述符可以用来访问该套接字,它的原型如下:

int socket(int domain, int type, int protocol); 

函数中的三个参数分别对应前面所说的三个套接字属性。protocol参数设置为0表示使用默认协议。

2、命名(绑定)套接字——bind系统调用

该函数把通过socket调用创建的套接字命名,从而让它可以被其他进程使用。对于AF_UNIX,调用该函数后套接字就会关联到一个文件系统路径名,对于AF_INET,则会关联到一个IP端口号。函数原型如下:

int bind( int socket, const struct sockaddr *address, size_t address_len); 

成功时返回0,失败时返回-1;

3、创建套接字队列(监听)——listen系统调用

该函数用来创建一个队列来保存未处理的请求。成功时返回0,失败时返回-1,其原型如下:

int listen(int socket, int backlog); 

backlog用于指定队列的长度,等待处理的进入连接的个数最多不能超过这个数字,否则往后的连接将被拒绝,导致客户的连接请求失败。调用后,程序一直会监听这个IP端口,如果有连接请求,就把它加入到这个队列中。

4、接受连接——accept系统调用

该系统调用用来等待客户建立对该套接字的连接。accept系统调用只有当客户程序试图连接到由socket参数指定的套接字上时才返回,也就是说,如果套接字队列中没有未处理的连接,accept将阻塞直到有客户建立连接为止。accept函数将创建一个新套接字来与该客户进行通信,并且返回新套接字的描述符,新套接字的类型和服务器监听套接字类型是一样的。它的原型如下:

int accept(int socket, struct sockaddr *address, size_t *address_len); 

address为连接客户端的地址,参数address_len指定客户结构的长度,如果客户地址的长度超过这个值,它将会截断。

5、请求连接——connect系统调用

该系统调用用来让客户程序通过在一个未命名套接字和服务器监听套接字之间建立连接的方法来连接到服务器。它的原型如下:

int connect(int socket, const struct sockaddr *address, size_t address_len); 

参数socket指定的套接字连接到参数addres指定的服务器套接字。成功时返回0,失败时返回-1.

6、关闭socket——close系统调用

该系统调用用来终止服务器和客户上的套接字连接,我们应该总是在连接的两端(服务器和客户)关闭套接字。

六、进程使用流式socket进行通信

下面用多个客户程序和一个服务器程序来展示进程间如何利用套接字进行通信。

sockserver.c是一个服务器程序,它首先创建套接字,然后绑定一个端口再监听套接字,忽略子进程的停止消息等,然后它进入循环,一直循环检查是否有客户连接到服务器,如果有,则调用fork创建一个子进程来处理请求。利用read系统调用来读取客户端发来的信息,利用write系统调用来向客户端发送信息。这个服务器的工作非常简单,就是把客户发过来的字符+1,再发送回给客户。

sockclient.c是一个客户程序,它同样要先创建套接,然后连接到指定IP端口服务器,如果连接成功,就用write来发送信息给服务器,再用read获取服务器处理后的信息,再输出。

服务器sockserver.c的源代码如下:

#include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> int main() {   int server_sockfd = -1;   int client_sockfd = -1;   int client_len = 0;   struct sockaddr_in server_addr;   struct sockaddr_in client_addr;   //创建流套接字   server_sockfd = socket(AF_INET, SOCK_STREAM, 0);   //设置服务器接收的连接地址和监听的端口   server_addr.sin_family = AF_INET;//指定网络套接字   server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//接受所有IP地址的连接   server_addr.sin_port = htons(9736);//绑定到9736端口   //绑定(命名)套接字   bind(server_sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));   //创建套接字队列,监听套接字   listen(server_sockfd, 5);   //忽略子进程停止或退出信号   signal(SIGCHLD, SIG_IGN);   while(1)   {     char ch = '\0';     client_len = sizeof(client_addr);     printf("Server waiting\n");     //接受连接,创建新的套接字     client_sockfd = accept(server_sockfd, (struct sockaddr*)&client_addr, &client_len);     if(fork() == 0)     {       //子进程中,读取客户端发过来的信息,处理信息,再发送给客户端       read(client_sockfd, &ch, 1);       sleep(5);       ch++;       write(client_sockfd, &ch, 1);       close(client_sockfd);       exit(0);     }     else     {       //父进程中,关闭套接字       close(client_sockfd);     }   } }

客户sockclient.c的源代码如下:

#include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> int main() {   int sockfd = -1;   int len = 0;   struct sockaddr_in address;   int result;   char ch = 'A';   //创建流套接字   sockfd = socket(AF_INET, SOCK_STREAM, 0);   //设置要连接的服务器的信息   address.sin_family = AF_INET;//使用网络套接字   address.sin_addr.s_addr = inet_addr("127.0.0.1");//服务器地址   address.sin_port = htons(9736);//服务器所监听的端口   len = sizeof(address);   //连接到服务器   result = connect(sockfd, (struct sockaddr*)&address, len);   if(result == -1)   {     perror("ops:client\n");     exit(1);   }   //发送请求给服务器   write(sockfd, &ch, 1);   //从服务器获取数据   read(sockfd, &ch, 1);   printf("char fORM server = %c\n", ch);   close(sockfd);   exit(0); }

运行结果如下:

Linux进程间通信中如何使用流套接字

在本例子中,我们启动了一个服务器程序和三个客户程序,从运行的结果来看,客户端发送给服务器程序的所有请求都得到了处理,即把A变成了B。对于服务器和客户程序之间使用的read和write系统调用跟使用命名管道时阻塞的read、write系统调用一样。例如客户程序调用read时,如果服务器程序没有向指定的客户程序的socket中写入信息,则read调用会一直阻塞。

七、流式套接字给我印象

给我的感觉是流式套接字很像命名管道,但是它却可以使不在同一台计算机而通过网络连接的不同计算机上的进程进行通信,功能真是非常的强大。

以上是“Linux进程间通信中如何使用流套接字”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网操作系统频道!

--结束END--

本文标题: Linux进程间通信中如何使用流套接字

本文链接: https://www.lsjlt.com/news/256725.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Linux进程间通信中如何使用流套接字
    小编给大家分享一下Linux进程间通信中如何使用流套接字,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!进程间的通信,所通信的进程都是在同一台计算机上的,而使用so...
    99+
    2023-06-09
  • Linux进程间通信——使用流套接字
    前面说到的进程间的通信,所通信的进程都是在同一台计算机上的,而使用socket进行通信的进程可以是同一台计算机的进程,也是可以是通过网络连接起来的不同计算机上的进程。通常我们使用socket进行网络编程,这...
    99+
    2022-06-04
    进程 通信 Linux
  • Linux进程间如何通信
    这篇文章主要介绍“Linux进程间如何通信”,在日常操作中,相信很多人在Linux进程间如何通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux进程间如何通信”的疑惑...
    99+
    2024-04-02
  • Linux进程间通信中如何使用消息队列
    本篇文章给大家分享的是有关Linux进程间通信中如何使用消息队列,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、什么是消息队列消息队列提供了一种从一个进程向另一个进程发送一个...
    99+
    2023-06-16
  • 如何使用Python中的进程间通信
    如何使用Python中的进程间通信进程间通信(IPC,Inter-Process Communication)是计算机科学中一个重要的概念,它允许不同的进程在同一个计算机系统中进行数据交换和共享资源。在Python中,有多种方式可以实现进程...
    99+
    2023-10-22
    Python 进程通信 IPC
  • php 进程通信系列 (五)socket unix域套接字
    php 进程通信系列 (五)socke unix域套接字 常见进程通信方式Unix socket (套接字)介绍一些理论基础:我们来看看php创建 无命名本地域 socket 的函数:命名Un...
    99+
    2023-10-10
    php
  • python中进程间如何通信
    今天就跟大家聊聊有关python中进程间如何通信,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。python有哪些常用库python常用的库:1.requesuts;2.scrapy;...
    99+
    2023-06-14
  • Android进程间如何使用Intent进行通信
    这篇文章主要介绍“Android进程间如何使用Intent进行通信”,在日常操作中,相信很多人在Android进程间如何使用Intent进行通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android进程...
    99+
    2023-07-05
  • C++中如何使用管道实现进程间通信
    在C++中使用管道实现进程间通信可以通过以下步骤: 包含相关的头文件: #include <iostream> #i...
    99+
    2024-04-02
  • Android进程间使用Intent进行通信
    安卓使用Intent来封装程序的“调用意图”,使用Intent可以让程序看起来更规范,更易于维护。 除此之外,使用Intent还有一个好处:有些时候我们只是想...
    99+
    2023-02-28
    Android Intent通信 Android进程通信
  • 如何在python中使用套接字
    这期内容当中小编将会给大家带来有关如何在python中使用套接字,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。python是什么意思Python是一种跨平台的、具有解释性、编译性、互动性和面向对象的脚本语...
    99+
    2023-06-14
  • C++中父子进程之间如何通信
    在C++中,父进程和子进程之间可以通过管道、共享内存、信号量、消息队列等方式进行通信。下面分别介绍这些通信方式: 管道(Pipe...
    99+
    2024-04-02
  • Linux消息队列如何实现进程间通信
    这篇文章主要介绍Linux消息队列如何实现进程间通信,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Linux消息队列实现进程间通信实例详解一、什么是消息队列消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法...
    99+
    2023-06-09
  • 基于Android AIDL进程间通信接口使用介绍
    AIDL:Android Interface Definition Language,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。 I...
    99+
    2022-06-06
    通信接口 aidl 通信 接口 Android
  • Electron进程间通信如何实现
    今天小编给大家分享一下Electron进程间通信如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。使用Electron开...
    99+
    2023-06-30
  • 如何在CentOS中使用ss命令查看套接字信息
    要在CentOS中使用ss命令查看套接字信息,可以按照以下步骤操作: 打开终端窗口,输入以下命令来查看所有的套接字信息: ss ...
    99+
    2024-04-02
  • 管道、套接字和共享内存:进程通信的秘密武器
    管道 管道是一种半双工通信机制,它允许两个相关进程在同一主机上进行通信。管道创建时,会建立一个缓冲区,用于存储进程之间交换的数据。写入进程将数据写入缓冲区,而读取进程从缓冲区中读取数据。管道具有以下特点: 专用且高效,仅限于相关进程使用...
    99+
    2024-04-02
  • 如何使用 Golang 协程进行通信?
    在 go 中使用协程进行通信,通道是一种基本机制,用于在协程之间发送和接收数据。通过使用发送( 使用 Golang 协程进行通信 在 Go 语言中,协程提供了并发编程的一种轻量级且高效...
    99+
    2024-05-21
    golang 协程
  • Python如何通过队列实现进程间通信
    本篇内容主要讲解“Python如何通过队列实现进程间通信”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python如何通过队列实现进程间通信”吧!一、前言在多进程中,每个进程之间是什么关系呢?其...
    99+
    2023-07-02
  • Cassandra中如何进行节点间通信
    Cassandra中节点之间的通信是由Gossip协议控制的。Gossip协议是一种用于节点之间通信和信息交换的分布式协议,用于传播...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作