有什么软件可以将套接字进程间通信必须使用套接字接口数据转换为串口形式的数据输出?

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

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

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

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

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

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

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

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

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

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

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

使用socket进行进程进程间通信必须使用套接字的进程采用的客户/服务器系統是如何工作的呢?

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

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

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

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

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

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

五、流式socket的接口及作用

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

六、进程使用流式socket进行进程间通信必须使用套接字

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

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

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

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

七、流式套接字给我印象

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

Socket接口是TCP/IP网络的API定义了一系列函數,程序员可以调用它们来开发TCP/IP网络上的应用程序Socket接口设计者最早是将接口放在Unix操作系统里面的,网络的Socket数据传输是一种特殊的I/O也是┅种文件描述符。有一个类似于文件打开的函数调用Socket()该函数返回一个整形的文件描述符,随后的连接建立、数据传输等是通过该Socket实现的

常用的套接字类型有两种:面向连接的流式(STOCK_STREAM)和无连接的数据报式(STOCK_DGRAM),前者针对TCP应用后者针对UDP应用。

前一篇文章Linux进程间进程间通信必须使用套接字——使用流套接字介绍了一些有关socket(套接字)的一些基本内容,并讲解了流套接字的使用这篇文章将会给大家讲讲,数據报套接字的使用

一、简单回顾——什么是数据报套接字

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

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

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

使用数据报socket进行进程进程間通信必须使用套接字的进程采用的客户/服务器系统是如何工作的呢?

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

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

不同的是然后系统调用recvfrom来接收来自客戶程序发送过来的数据。服务器程序对数据进行相应的处理再通过系统调用sendto把处理后的数据发送回客户程序。

1、在流套接字中的程序中接收数据是通过系统调用read,而发送数据是通过系统调用write来实现而在数据报套接字程序中,这是通过recvfrom和sendto调用来实现的

2、使用数据报套接字的服务器程序并不需要listen调用来创建一个队列来存储连接,也不需要accept调用来接收连接并创建一个新的socket描述符

基于数据报socket的客户端比服务器端简单同样,客户应用程序首先调用socket来创建一个未命名的套接字与服务器一样,客户也是通过sendto和recvfrom来向服务器发送数据和从服务器程序接收数据

使用数据报套接字的客户程序并不需要使用connect系统调用来连接服务器程序,它只要在需要时向服务器所监听的IP端口发送信息和接收从服务器发送回来的数据即可

三、数据报socket的接口及作用

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

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

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

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

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

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

3、发送数据——sendto系统调用

該函数把缓冲区buffer中的信息给送给指定的IP端口的程序,原型如下:

buffer中储存着将要发送的数据len是buffer的长度,而flags在应用中通常被设置为0to是要发送数据到的程序的IP端口,tolen是to参数的长度

成功时返回发送的数据的字节数,失败时返回-1.

4、接收数据——recvfrom系统调用

该函数把发送给程序的信息储存在缓冲区buffer中并记录数据来源的程序IP端口,原型如下:
 

buffer用于储存接收到的数据len指定buffer的长度,而flags在应用中通常被设置0src_from若不为空,則记录数据来源程序的IP端口若src_len不为空,则其长度信息记录在src_len所指向的变量中

注意:默认情况下,recvfrom是一个阻塞的调用即直到它接收到數据才会返回。

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

四、进程使用数据报socket进行进程间通信必须使用套接字

下面用多个客户程序实例和一个服务器程序来演示多个进程如何通过使用数据报socket来进行进程间通信必须使用套接字

sockserver2.c是一个服务器程序,它接收客户程序发来的数据并创建一个子进程来处理客户发送过来的数据,处理过程非常简單就是把大写字母改为小写。然后把处理后的数据(大写字母对应的小写字母)发送回给客户端

sockclient2.c是一个客户程序,它向服务器程序发送数据并接收服务器发送过来的处理后的数据(即小写字母),然后把接收到的数据输出到屏幕上在运行客户程序时,你可以为它提供一个字符作为参数此时客户程序将把些字符作为要处理的数据发送给服务器,如果不提供一个参数则默认发送字符A。

//绑定(命名)套接字 //忽略子进程停止或退出信号 //接收数据用client_addr来储存数据来源程序的IP端口 //利用子进程来处理数据 //注意,一定要关闭子进程否则程序运荇会不正常
//取第一个参数的第一个字符 //设置服务器IP端口 //接收服务器处理后发送过来的数据,由于不关心数据来源所以把后两个参数设为0

先运行服务器程序,如下:

再运行三个客户端:如下:

在本例子中我们启动了一个服务器程序和三个客户程序,从运行的结果来看客戶端发送给服务器程序的所有请求都得到了处理,即把大写字母变成了小写recvfrom调用是阻塞的调用,即只有当接收到数据才会返回

五、数據报套接字与流套接字的比较

1、从使用的便利和效率来讲

我们可以看到使用数据报套接字的确是比使用流套接字简单,而且快速

因为使鼡流套接字的程序,客户程序需要调用connect来创建一个到服务器程序的连接并需要维持这个连接,服务器程序也需要调用listen来创建一个队列来保存未处理的请求当有数据到达时,服务器也不需要调用accept来接受连接并创建一个新socket描述符来处理请求

再来看看使用数据报套接字的程序,服务器程序与客户程序所使用的系统调用大致相同服务器程序只比客户程序多使用了一个bind调用。基于数据报套接字的程序只需要使用sendto调用来向指定IP端口的程序发送信息,使用recvfrom调用从指向的IP端口接收信息即可因为它并不需要建立一个连接,接受连接等所以省去了佷多的功夫。

我们知道流套接字是基于TCP/IP协议的它是一种安全的协议,提供的是一个有序、可靠、双向字节流的连接发送的数据可以确保不会丢失、重复或乱序到达,而且它还有一定的出错后重新发送的机制所以它比较适合用来发送信息量大的数据文件,或对数据完整性要求较高的文件如压缩文件、视频文件等

而数据报套接字是基于UDP/IP协议实现的。它对可以发送的数据的长度有限制数据报作为一个单獨的网络消息被传输,它可能会丢失、复制或错乱到达,UDP不是一个可靠的协议但是它的速度比较高。所以它比较适合发送一些对实时性要求较高但是对安全性和完整性要求不太高的数据。如我们熟悉的聊天信息即使有一点的丢失也不会造成理解上的大的问题。

我要回帖

更多关于 套接字通信 的文章

 

随机推荐