版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、吉林大学软件学院吉林大学软件学院第第2章章 UNIX中的套接字网络编程接口中的套接字网络编程接口lUNIX套接字网络编程接口的产生与发展过程l套接字与UNIX操作系统的关系l套接字编程的基本概念l套接字的特点、应用场合、使用的数据类型l面向连接的套接字编程l套接字的工作过程、系统调用、编程实例l借助实例分析进程的阻塞问题和对策l无连接的套接字编程l无连接套接字编程的两种模式(C/S和对等)l数据报套接字的对等模式编程实例 吉林大学软件学院吉林大学软件学院2.1 UNIX套接字网络编程接口的产生与发展套接字网络编程接口的产生与发展2.1.1 问题的提出问题的提出l应用程序与协议软件进行交互时须说
2、明许多细节应用程序与协议软件进行交互时须说明许多细节:l是服务器还是客户机,主动还是被动通信?l发送方需说明发送的数据;l接收方需说明接收的数据如何存放。l站在应用程序实现的角度,应用程序如何方便地使用协议栈软件进行通信呢?l如果能在应用程序与协议栈软件之间提供一个软件接口,就可以方便客户与服务器软件的编程。lUNIX最早将最早将TCP/IP协议簇集成到内核中,协议簇集成到内核中,UNIX的开发者提出并实现了套接字应用编程接口。的开发者提出并实现了套接字应用编程接口。吉林大学软件学院吉林大学软件学院l套接字应用程序编程接口:套接字应用程序编程接口:是网络应用程序通过网是网络应用程序通过网络协议
3、栈进行通信时所使用的接口,即应用程序与络协议栈进行通信时所使用的接口,即应用程序与协议栈软件之间的接口,简称协议栈软件之间的接口,简称套接字编程接口套接字编程接口(Socket API)。l定义了应用程序与协议栈软件进行交互时可以使用的一组操作,决定了应用程序使用协议栈的方式、应用程序所能实现的功能、以及开发具有这些功能的程序的难度。l套接字编程接口给出了应用程序能够调用的一组过程,以及这些过程所需的参数,每个独立的过程完成一个与协议栈软件交互的基本操作(如:建立连接、接收数据、释放链接)。吉林大学软件学院吉林大学软件学院2.1.2 套接字编程接口的起源与应用套接字编程接口的起源与应用l加州大
4、学伯克利分校开发了一个包括TCP/IP协议簇的BSD UNIX,并迅速得到推广,套接字编程接口是这个操作系统的一部分。lTCP/IP标准并没有定义应用程序用来与该协议进标准并没有定义应用程序用来与该协议进行交互的应用程序编程接口,只规定了应该提供行交互的应用程序编程接口,只规定了应该提供的一般操作,并允许各个操作系统去定义用来实的一般操作,并允许各个操作系统去定义用来实现这些操作的具体现这些操作的具体API。l一个协议标准可能只是建议某个操作在应用程序发送数据时是需要的,而由应用程序编程接口来定义具体的函数名和每个参数的类型。吉林大学软件学院吉林大学软件学院l尽管协议标准允许操作系统设计者开发
5、自己的应尽管协议标准允许操作系统设计者开发自己的应用程序编程接口,但由于用程序编程接口,但由于BSD UNIX的广泛使用,的广泛使用,后来的许多操作系统及编程语言都选择了对套接后来的许多操作系统及编程语言都选择了对套接字编程接口的支持。字编程接口的支持。l由于这个套接字规范最早是由由于这个套接字规范最早是由Berkeley大学开发的,大学开发的,一般将它称为一般将它称为Berkeley Sockets规范。规范。lBerkeley Sockets规范规定了一系列与套接字使用有关的库函数,为在UNIX操作系统下不同计算机中的应用程序进程之间,使用TCP/IP协议簇进行网络通信提供了一套应用程序编
6、程接口。吉林大学软件学院吉林大学软件学院2.1.3 套接字编程接口的两种实现方式套接字编程接口的两种实现方式l采用两种实现套接字编程接口的方式:采用两种实现套接字编程接口的方式:l在操作系统的内核中增加相应的软件来实现;l通过开发操作系统之外的函数库来实现。 l在在BSD UNIX及起源于它的操作系统中,套接字函数是及起源于它的操作系统中,套接字函数是操作系统本身的功能调用,是操作系统内核的一部分。操作系统本身的功能调用,是操作系统内核的一部分。l其他操作系统供应商为了不修改基本操作系统,开发了其他操作系统供应商为了不修改基本操作系统,开发了套接字库(套接字库(Socket Library)来
7、提供套接字编程接口。)来提供套接字编程接口。l套接字库中的每个过程具有与UNIX套接字函数相同的名字与参数,向没有本机套接字的操作系统上的应用程序提供套接字编程接口。l套接字库与操作系统内核中实现的套接字套接字库与操作系统内核中实现的套接字在语义在语义上是相同的上是相同的。l应用程序调用套接字过程不必管它是由操作系统内核过程提供的,还是由库过程提供的。l这种方式提供了程序的可移植性:将程序从一台计算机移植到另一台计算机时,程序的源代码不需改动,只要用新计算机上的套接字库重新编译即可。l套接字库与操作系统直接提供的本机套接字编程套接字库与操作系统直接提供的本机套接字编程接口接口在实现上是不同的在
8、实现上是不同的。l套接字库的过程需要链接到应用程序中;l并驻留于应用程序地址空间;l调用时控制从应用程序转向库程序,并进一步调用一个或多个底层操作系统的功能调用。2.1.4 套接字通信与套接字通信与UNIX操作系统的输入操作系统的输入/输出输出l套接字编程接口采用传统的套接字编程接口采用传统的UNIX输入输入/输出模式。输出模式。lUNIX操作系统对文件和所有其它操作系统对文件和所有其它的输入的输入/输出设备输出设备采用一种统一的操作模式,就是采用一种统一的操作模式,就是“打开打开-读读-写写-关闭关闭”(open - read - write - close)的的I/O模式。模式。l调用op
9、en命令获得对指定文件或设备的使用权,并返回一个用来标识该文件或设备的短整型描述符,作为用户在打开的文件或设备上进行I/O的句柄。l多次调用read或write命令来传输数据,期间用描述符作为命令的参数,指明要操作的对象。l传输完成后调用close命令,通知操作系统已经完成了对某对象的调用,释放所占用的资源。吉林大学软件学院吉林大学软件学院l当当TCP/IP协议被集成到协议被集成到UNIX内核中的时候,相当内核中的时候,相当于在于在UNIX系统中引入了一种新型的系统中引入了一种新型的I/O操作。操作。l应用程序通过网络协议栈来交换数据。l操作系统和应用程序都将套接字编程接口也看作一操作系统和应
10、用程序都将套接字编程接口也看作一种输入种输入/输出机制。输出机制。l操作过程类似,创建套接字-使用-删除;l操作方法类似,申请生成一个套接字后,系统返回一个短整型描述符来标识这个套接字对象;l使用的过程名可以是相同的,如write过程可以将数据发送给另一个程序、文件或网络中的另一个进程。吉林大学软件学院吉林大学软件学院lUNIX系统对于各种系统对于各种I/O的集成提供了灵活性。的集成提供了灵活性。l应用程序可以编写成向任何地方传输数据,取决于描述符对象代表什么(设备、文件、套接字)。l系统对套接字和其它I/O使用相同的描述符空间,使得单个应用程序既可以进行网络通信,又可以实现本地数据传输。l用
11、户进程与网络协议的交互,实际要比用户进程与用户进程与网络协议的交互,实际要比用户进程与传统传统I/O设备的交互复杂得多。设备的交互复杂得多。l仅提供open、read、write、close四个过程远不够.l使用套接字的应用程序必须说明许多细节。使用套接字的应用程序必须说明许多细节。l应用程序使用的协议簇、远程计算机的地址、该应用程序是客户机还是服务器、希望的服务类型是面向连接的还是无连接的,等等。l为了提供这些细节,每个套接字有许多参数与为了提供这些细节,每个套接字有许多参数与选项,需要应用程序提供具体值。选项,需要应用程序提供具体值。l为避免单个套接字函数参数过多,套接字编程接口的设计者定
12、义了多个函数。l例如,创建套接字时,先调用一个函数创建套接字,再调用其它函数说明使用套接字的细节。吉林大学软件学院吉林大学软件学院2.2 套接字编程的基本概念套接字编程的基本概念图图2.1 电插座与电话插座的作用电插座与电话插座的作用2.2.1 什么是套接字(什么是套接字(SOCKET) l套接字是对网络中不同主机上应用进程之间进行双向套接字是对网络中不同主机上应用进程之间进行双向通信的端点的抽象。通信的端点的抽象。l一个套接字就是网络上进程通信的一端,提供了应用一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议栈交换数据的机制层进程利用网络协议栈交换数据的机制。 吉林大学软件学
13、院吉林大学软件学院图图2.2 应用进程、套接口、网络协议栈及操作系统的关系应用进程、套接口、网络协议栈及操作系统的关系 l两个应用进程只要分别连接到自己的套接字,就可以通过网络痛惜,不用去管复杂的网络结构及数据传输过程。l从多个层面来理解套接字这个概念的内涵从多个层面来理解套接字这个概念的内涵l从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议栈进行通信的接口,是应用程序与网络协议栈交互的接口. l从实现的角度来讲,非常复杂。套接字是一个复杂的软件机构,包含了一定的数据结构,包含许多选项,由操作系统内核管理。l从使用的角度来讲,非常简单。对套接字的操作形成了一种网络应
14、用程序的编程接口(API),提供了一组系统调用或库函数,可以用于构造套接字、安装绑定套接字、连接套接字、通过套接字交换数据、关闭套接字,实现各种分布式应用。是一套操作套接字的编程接口函数,是一套操作套接字的编程接口函数,套接字是它的操作对象。套接字是它的操作对象。吉林大学软件学院吉林大学软件学院2.2.2 套接字的特点套接字的特点1 1通信域通信域l通信域:通信域:是一个计算机网络的范围,在这个范围中,所有的计算机使用同一种网络体系结构及协议栈。l套接字存在于通信域中。套接字存在于通信域中。l套接字通常只和同一域中的套接字交换数据。l如果数据交换要穿越域的边界,就一定要执行某种解释程序。l这里
15、,仅仅针对这里,仅仅针对Internet域,并且使用域,并且使用Internet协协议族(即议族(即TCP/IP协议族)来通信。协议族)来通信。吉林大学软件学院吉林大学软件学院2 2套接字具有三种类型套接字具有三种类型l每一个正被使用的套接字都有它确定的类型。l只有相同类型的套接字才能相互通信。(1) 数据报套接字(数据报套接字(Datagram SOCKET)l数据报套接字提供无连接的、不保证可靠的、独数据报套接字提供无连接的、不保证可靠的、独立的数据报传输服务。立的数据报传输服务。l在在Internet通信域中,数据报套接字使用通信域中,数据报套接字使用UDP数据数据报协议形成的进程间通路
16、,具有报协议形成的进程间通路,具有UDP协议为上层协议为上层所提供的服务的所有特点。所提供的服务的所有特点。l一般用于轻载通信,并具有多播通信的能力。一般用于轻载通信,并具有多播通信的能力。吉林大学软件学院吉林大学软件学院图图2.3 在在Internet通信域中,数据报套接字基于通信域中,数据报套接字基于UDP协议协议 吉林大学软件学院吉林大学软件学院(2) 流式套接字(流式套接字(Stream SOCKET)l流式套接字提供双向的、有序的、无重复的、无流式套接字提供双向的、有序的、无重复的、无记录边界的可靠的数据流传输服务。记录边界的可靠的数据流传输服务。l在在Internet通信域中,流式
17、套接字使用通信域中,流式套接字使用TCP协议形协议形成的进程间通路,具有成的进程间通路,具有TCP协议为上层所提供的协议为上层所提供的服务的所有特点。服务的所有特点。l在使用流式套接字传输数据之前,必须在数据的在使用流式套接字传输数据之前,必须在数据的发送端和接收端之间建立连接。发送端和接收端之间建立连接。 l一般用于交换大批量的数据时,或者要求数据按一般用于交换大批量的数据时,或者要求数据按照发送的顺序无重复的到达目的地的时候。照发送的顺序无重复的到达目的地的时候。吉林大学软件学院吉林大学软件学院图图2.4 在在Internet通信域中,流式套接字基于通信域中,流式套接字基于TCP协议协议吉
18、林大学软件学院吉林大学软件学院(3) 原始式套接字(原始式套接字(RAW SOCKET)l原始式套接字允许对较低层次的协议原始式套接字允许对较低层次的协议(如如IP、ICMP)直接访问,用于检验新协议的实现。直接访问,用于检验新协议的实现。l原始套接字保存了数据包中的完整IP头;l前面两种套接字只能收到用户数据;l因此可以通过原始套接字对数据进行分析。 吉林大学软件学院吉林大学软件学院3 3套接字的创建套接字的创建l套接字由应用层的通信进程创建,并为其服务。套接字由应用层的通信进程创建,并为其服务。l即,每一个套接字都有一个相关的应用进程,操作即,每一个套接字都有一个相关的应用进程,操作该套接
19、字的代码是该进程的组成部分。该套接字的代码是该进程的组成部分。 4 4使用确定的使用确定的IPIP地址和传输层端口号地址和传输层端口号l在生成套接字的描述符后,要将套接字与计算机上在生成套接字的描述符后,要将套接字与计算机上的特定的的特定的IP地址和传输层端口号相关联,这个过程地址和传输层端口号相关联,这个过程称为称为绑定绑定。l 一个套接口要使用一个确定的三元组网络地址信息,一个套接口要使用一个确定的三元组网络地址信息,才能使它在网络中唯一地被标识。才能使它在网络中唯一地被标识。吉林大学软件学院吉林大学软件学院2.2.3 套接字的应用场合套接字的应用场合l并非所有的网络应用编程都要使用套接字
20、。并非所有的网络应用编程都要使用套接字。l套接字适合开发具有如下特点的新网络应用。套接字适合开发具有如下特点的新网络应用。l不管是采用对等模式或者客户机/服务器模式,通信双方的应用程序都需要开发。l双方所交换数据的结构和交换数据的顺序有特定的要求,不符合现在成熟的应用层协议,甚至需要自己去开发应用层协议,自己设计最适合的数据结构和信息交换规程。 l套接字编程层次较低,自由度较大。套接字编程层次较低,自由度较大。吉林大学软件学院吉林大学软件学院2.2.4 套接字使用的数据类型和相关的问题套接字使用的数据类型和相关的问题1 1三种表示套接字地址的结构三种表示套接字地址的结构l在套接字编程接口中,定
21、义了三种结构型的数据类型,在套接字编程接口中,定义了三种结构型的数据类型,用来存储协议相关的网络地址,在套接字编程接口的用来存储协议相关的网络地址,在套接字编程接口的函数调用中要用到它们。函数调用中要用到它们。(1) sockaddr结构:结构:针对各种通信域的套接字,用来表示地址的一般格式,然后要求每个协议族说明其协议地址如果具体使用这个一般格式的。struct sockaddr u_charsa_len; / 地址总长u_char sa_family; / 地址家族charsa_data14; / 协议地址 (2) sockaddr_in结构:结构:专门针对Internet通信域,存储套接
22、字相关的网络地址信息,例如IP地址,传输层端口号等信息。struct sockaddr_in u_charsa_len; / 地址总长u_char sin_family;/ 地址家族,必须设定为u_shortsin_port;/ 端口号,2字节struct in_addr sin_addr;/ IP 地址,4字节charsin_zero8;/ 未用,全为0 ,8字节 (3) in_addr结构:结构:专门用来存储 IP地址。Struct in_addr Unsigned long s_addrl;AF_INET14字节字节(4) 这些数据结构的一般用法这些数据结构的一般用法l首先,定义一个首先
23、,定义一个sockaddr_in的结构实例,并将它清的结构实例,并将它清零。零。struct sockaddr_in myad;memset(&myad,0,sizeof(struct sockaddr_in); l然后,为这个结构赋值。然后,为这个结构赋值。myad.sin_family=AF_INET;myad.sin_port=htons(8080); myad.sin_addr.s_addr=htonl(INADDR-ANY);l第三步,在函数调用中使用时,将这个结构强制转第三步,在函数调用中使用时,将这个结构强制转换为换为sockaddr类型。类型。accept(listen
24、fd,(sockaddr*)(&myad),&addrlen); 吉林大学软件学院吉林大学软件学院2 2本机字节顺序和网络字节顺序本机字节顺序和网络字节顺序l本机字节顺序:本机字节顺序:在具体计算机中的多字节数据的存在具体计算机中的多字节数据的存储顺序。储顺序。l网络字节顺序:网络字节顺序:多字节数据在网络协议报头中的存多字节数据在网络协议报头中的存储顺序。储顺序。l网络应用程序要在不同的计算机中运行,本机字节网络应用程序要在不同的计算机中运行,本机字节顺序是不同的,但网络字节顺序是一定的。顺序是不同的,但网络字节顺序是一定的。l所以,在应用程序编程的时候,在把所以,在应用程序
25、编程的时候,在把IP地址和端口地址和端口号装入套接字时,应当把它们从本机字节顺序转换号装入套接字时,应当把它们从本机字节顺序转换为网络字节顺序;相反,在本机输出时,应将它们为网络字节顺序;相反,在本机输出时,应将它们从网络字节顺序转换为本机字节顺序。从网络字节顺序转换为本机字节顺序。吉林大学软件学院吉林大学软件学院l套接字编程接口为解决这个问题设置了四个函数:套接字编程接口为解决这个问题设置了四个函数:lhtons() 短整数本机顺序转换为网络顺序,用于端口号。lhtonl() 长整数本机顺序转换为网络顺序,用于IP地址。lntohs() 短整数网络顺序转换为本机顺序,用于端口号。lntohl
26、() 长整数网络顺序转化为本机顺序,用于IP地址。l这四个函数将被转换的数值作为函数的参数,函数这四个函数将被转换的数值作为函数的参数,函数返回值是转换后的结果。返回值是转换后的结果。 吉林大学软件学院吉林大学软件学院3 3点分十进制的点分十进制的IPIP地址的转换地址的转换l在因特网中,IP地址常用点分十进制的表示方法,在套接字中,IP地址是无符号的长整型数,套接字接口设置了两个函数用于两种形式IP地址的转换。(1) inet-addr函数函数unsigned long inet-addr( const char* cp)l入口参数入口参数cp:点分十进制形式的:点分十进制形式的IP地址。地
27、址。l返回值:返回值: 网络字节顺序的网络字节顺序的IP地址,是无符号的长地址,是无符号的长整数。整数。吉林大学软件学院吉林大学软件学院(2) inet_ntoa函数函数char* inet_ntoa(struct in_addr in)l入口参数入口参数in:包含长整型:包含长整型IP地址的地址的 in_addr 结构变结构变量;量;l返回值:返回值: 指向点分十进制指向点分十进制IP地址的字符串的指针地址的字符串的指针. 吉林大学软件学院吉林大学软件学院4 4域名服务域名服务l通常,我们使用域名来标识站点,可以将文字型的主机域名直接转换成IP地址。struct hostent* getho
28、stbyname( const char* name);l入口参数:是站点的主机域名字符串;入口参数:是站点的主机域名字符串;l返回值:返回值:是指向是指向hostent 结构的指针。结构的指针。lhostent结构包含主机名、主机别名数组、返回地址的类型(一般是AF-INET)、地址长度的字节数、已符合网络字节顺序的主机网络地址等。 吉林大学软件学院吉林大学软件学院2.3 面向连接的套接字编程面向连接的套接字编程2.3.1 套接字的工作过程套接字的工作过程l面向连接的通信方式基于面向连接的通信方式基于TCP,必须借助流式套,必须借助流式套接字来编程,应用服务器分为服务器端和客户端,接字来编程
29、,应用服务器分为服务器端和客户端,双方是不对称的,需要分别编程。双方是不对称的,需要分别编程。l双方首先要创建并安装套接字,做好准备;l建立连接,采用三次握手的方式;l数据交换,称为客户机与服务器的会话期,会话的内容必须遵守一定的格式和顺序;l释放连接。l下面介绍面向连接的服务器和客户端的编程步骤下面介绍面向连接的服务器和客户端的编程步骤.吉林大学软件学院吉林大学软件学院2.3.2 UNIX套接字编程接口的系统调用套接字编程接口的系统调用1创建套接字创建套接字SOCKET()l创建一个套接字,并返回一个整型描述符:创建一个套接字,并返回一个整型描述符:int SOCKET( int Proto
30、family, int Type, int Protocol); l入口参数:入口参数:lProtofamily:套接字使用的协议簇,一般为PF_INET,表示TCP/IP协议簇,PF_DECnet表示DEC协议。 ltype:套接字类型,SOCK_STREMA表示创建面向连接的流传输的流式套接字;SOCK_DGRAMA表示创建无连接的面向消息的数据报套接字。 lprotocol:套接字使用的传输层网络协议,一般为IPPROTO_IP,internet通信域中一般取值为0。 吉林大学软件学院吉林大学软件学院l返回值:返回值:l套接字创建成功,返回一个int型的整数,即所创建套接字的描述符,指向
31、被维护在操作系统内核里的socket数据结构。l套接字创建出错,返回1,表示出错类型的代码保存在全局变量Errno中。l举例:举例:int sockfd=SOCKET(PF_INTE,SOCK_STREAM,0)l创建套接字时,为其分配了内存,并建立了相应的数据结构,用于指定连接的种类和使用的协议,同时还有关于连接队列操作的选项结构字段,创建时设置为默认值。吉林大学软件学院吉林大学软件学院2绑定套接字到指定的地址绑定套接字到指定的地址 BIND()lint BIND( int Sockfd, struct sockaddr* My_addr, int Addrlen); l入口参数:入口参数:
32、lSockfd:是由SOCKET()系统调用创建的套接字描述符,要将其绑定到指定的网络地址上;lMy_addr:指向sockaddr结构变量的指针,所指结构中保存着特定的网络地址,要将套接字绑定到这个网络地址上;lAddlen:是sockaddr结构的长度。吉林大学软件学院吉林大学软件学院l返回值:返回值:l如果返回0,表示已经绑定成功。l如果返回1,表示有错,出错码在Errno中。l举例:举例:Struct sockaddr_in my_addr;if( BIND(sockfd, (sockaddr*)&my_addr ,sizeof(struct sockaddr_in) )0 )
33、 报错,并退出l在服务器端,用作监听客户机连接请求的套接字一定要绑定,因为大多数服务器进程使用熟知端口,并且服务器有时有多块网卡,会有多个IP地址。l客户机一般不用绑定。吉林大学软件学院吉林大学软件学院l返回值:返回值:l如果返回0,表示已经绑定成功。l如果返回1,表示有错,出错码在Errno中。l服务器调用BIND,来说明它将用来接收通信的协议端口号,同时my_addr 结构中还包含记录IP地址的域,此时如果主机是多宿主机,则in_addr字段取值常量INADDR_ANY,允许服务器在该计算机的任何IP地址上使用一个指定的端口。吉林大学软件学院吉林大学软件学院3启动监听启动监听Listen(
34、)lint LISTEN( int Sockfd, int Queuesize);l入口参数:入口参数:lSockfd:套接字描述符,通过它来监听来自客户机端的连接请求。lQueuesize:等待连接队列的最大长度,最大可设为20,一般设为510。(操作系统为每个监听套接字建立一个用来等待连接的“先进先出”缓冲区队列,若缓冲区队列有空就接收一个客户端请求。)l返回值:返回值:l函数正确执行则返回0,出错则返回-1。l举例:举例:LISTEN(Sockfe,10);l本套接字只适用于面向连接的流式套接字。吉林大学软件学院吉林大学软件学院举例:举例:LISTEN(Sockfe, 10); 图图2.
35、6 监听套接字使用缓冲区接纳多个客户端的连接请求监听套接字使用缓冲区接纳多个客户端的连接请求 吉林大学软件学院吉林大学软件学院4接收连接请求接收连接请求ACCEPT()lint ACCEPT(int Sockfd, struct sockaddr* Addr, int* addrlen);l入口参数:入口参数:lSockfd:监听客户端连接请求的套接字描述符。lAddr:sockaddr结构变量的指针,是一个出口参数,当调用执行完毕时,变量中放置的是所接收客户机端的网络地址。lAddrlen:整型变量指针,也是一个出口参数,调用时初始设置为Addr结构的长度,不能为0或null,调用执行完毕时
36、,返回所接收的客户机端网络地址长度。吉林大学软件学院吉林大学软件学院l返回值:返回值:l如果执行正确,返回一个新的套接字描述符,这个套接字已经与客户机端建立了连接,并专用于此后与客户机端交换数据。l如果出错,返回1。l说明:说明:l调用从监听套接字的等待队列中,取出第一个连接请求,创建一个新的套接字,并通过这个新套接字向客户机端发送连接应答,从而与客户机端建立连接,系统为这个新的套接字分配一个服务器端的自由端口号,这个套接字用于后续与客户机端交换数据,称为响应套接字。吉林大学软件学院吉林大学软件学院l本调用仅适用于面向连接的流式套接字,与LISTEN()配套使用,两个入口参数能返回客户端的网络
37、地址.l本调用以阻塞的方式工作,若监听套接字的等待队列为空,则本调用就阻塞直到有连接请求的到来。l举例:int clientfd; / 定义响应套接字描述符变量int addrlen=sizeof(sockaddr); / 获得套接字地址结构长度。struct sockaddr_in cltsockaddr; / 定义用于返回客户端地址的结构。clientfd=ACCEPT(listenfd, (sockaddr* )(&cltsockaddr), &addrlen); / 接收客户连接请求 吉林大学软件学院吉林大学软件学院5请求建立连接请求建立连接CONNECT()lint
38、CONNECT( int Sockfd, struct sockaddr* Service_addr, int Addrlen);l入口参数:入口参数:lSockfd:客户机端的请求套接字;lService_addr:存放服务器端的网络地址;lAddrlen:sockaddr结构的长度。l返回值:返回值:l连接成功,返回0;l连接未成功,返回-1。吉林大学软件学院吉林大学软件学院l说明:说明:l用于客户端请求连接到服务器;l对于流式套接字,使用传输层TCP协议,服务器若接受连接请求,即把它放入监听套接字的缓冲区队列,并调用ACCEPT()来接收处理;l对于数据报套接字,使用传输层UDP协议,并
39、不建立连接,而只是将套接字置为connected的状态,客户机向同一服务器传送多条信息时,意义在于使用CONNECT在套接字中记录服务器的地址,允许客户机只指明服务器地址一次,而不必在每条信息中都指明目的地址。吉林大学软件学院吉林大学软件学院l举例:举例: if ( CONNECT(sockfd, (struct sockaddr*)(&serv_addr), sizeof(struct sockaddr) ) 0 ) 报错,并退出吉林大学软件学院吉林大学软件学院6读读/写套接字写套接字READ()和和WRITE()lint READ( int sockfd, void* buffer
40、, int len )lint WRITE( int sockfd, void* buffer, int len )l入口参数:入口参数:lSockfd:要读/写的套接字描述符,在客户机端是请求套接字,在服务器端是响应套接字;lBuffer:字符串变量的指针,指向内存中用来存放数据的读写缓冲区,读套接字时存放从套接字接收到的数据,写套接字的时候存放要发送的数据;lLen:读写缓冲区的长度。l返回值:返回值:l对于read()返回实际读到的字符数。吉林大学软件学院吉林大学软件学院l说明:说明:l套接字起源于UNIX,UNIX将套接字也统一使用read和write对I/O操作进行数据传输。l优点:
41、普遍性,应用程序能够创建一个发往或接收自一个描述符的数据传输,而不必知道这个描述符对应的是一个文件还是一个套接字。l缺点:套接字库的实现可能对所有使用套接字的应用增加额外的I/O开销。吉林大学软件学院吉林大学软件学院7发送发送 SEND() 和接收和接收 RECV()int SEND( int sockfd, char* buf, int len, int flags );int RECV( int sockfd, char* buf, int len, int flags ); l入口参数:入口参数:lsockfd:用来发送/接收数据的套接字描述符,可以是由SOCKET()创建的,也可以是A
42、CCEPT()返回的;lbuf:用于发送/接收数据的缓冲区指针;llen:要发送的或接收到的字符数;lflags:执行本调用的方式,一般置为0.吉林大学软件学院吉林大学软件学院l返回值:返回值:l处理错误,返回-1;l如果正确,对于发送返回实际发送出去的字节数;对于接收返回实际读入缓冲区的字节数。l说明:说明:l和read、write一样,必须用于已连接的套接字,无需调用者指明目的地参数。吉林大学软件学院吉林大学软件学院l8关闭套接字关闭套接字CLOSE() int CLOSE( int sockfd ); l入口参数:入口参数:lsockfd:要关闭的套接字描述符。l说明:说明:l如果是面向
43、连接的,CLOSE在关闭套接字前先终止连接;l关闭一个套接字意味着立即终止对它的使用,描述符被释放,以防止应用程序发送或接收更多的数据。吉林大学软件学院吉林大学软件学院2.3.3 面向连接的套接字编程实例面向连接的套接字编程实例1实例的功能实例的功能l服务器对来访的客户计数,并向客户报告这个计数值服务器对来访的客户计数,并向客户报告这个计数值; ;l客户建立与服务器的一个连接并等待它的输出;客户建立与服务器的一个连接并等待它的输出;l每当连接请求到达时,服务器生成一个可打印的每当连接请求到达时,服务器生成一个可打印的ASCIIASCII串信息,将它在连接上发回,然后关闭连接;串信息,将它在连接
44、上发回,然后关闭连接;l客户显示收到的信息,然后退出。客户显示收到的信息,然后退出。l例如,对于服务器接收的第10次客户连接请求,该客户将收到并打印如下信息:This server has been contacted 10 times. 吉林大学软件学院吉林大学软件学院2实例程序的命令行参数实例程序的命令行参数l实例是实例是UNIX环境下的环境下的C程序,客户和服务器程序程序,客户和服务器程序在编译后,均以命令行的方式执行。在编译后,均以命令行的方式执行。l服务器程序执行时可以带一个命令行参数,用来服务器程序执行时可以带一个命令行参数,用来接收请求的监听套接字的协议端口号。接收请求的监听套接
45、字的协议端口号。l这个参数是可选的,如果不指定端口号,代码将使用程序内定的缺省端口号5188。l客户程序执行时可以带两个命令行参数:客户程序执行时可以带两个命令行参数:l一个是服务器所在计算机的主机名;l另一个是服务器监听的协议端口号。吉林大学软件学院吉林大学软件学院l这两个参数都是可选的。l如果没有指定协议端口号,客户使用程序内定的缺省值5188。l如果一个参数也没有,客户使用缺省端口和主机名localhost,localhost是映射到客户所运行的计算机的一个别名。l允许客户与本地机上的服务器通信,对调试是很允许客户与本地机上的服务器通信,对调试是很有用的。有用的。 3客户程序代码客户程序
46、代码/*-* 程序:程序: client.c* 目的:目的: 创建一个套接字,通过网络连接一个服务器,并打印来创建一个套接字,通过网络连接一个服务器,并打印来自服务器的信息自服务器的信息* 语法:语法: client host port * host - 运行服务器的计算机的名字运行服务器的计算机的名字* port - 服务器监听套接字所用协议端口号服务器监听套接字所用协议端口号* 注意:两个参数都是可选的。如果未指定主机名,客户使用注意:两个参数都是可选的。如果未指定主机名,客户使用localhost;如果未指定端口号,;如果未指定端口号, * 客户将使用客户将使用PROTOPORT中给定的
47、缺省协议端口号中给定的缺省协议端口号*-*/ #include /* 基本系统数据类型基本系统数据类型*/#include /* UNIX下,套接字接口包含文件下,套接字接口包含文件*/#include /* Internet地址簇地址簇*/#include /* Internet定义定义*/#include /* 网络数据库操作网络数据库操作*/#include /* 标准输入输出标准输入输出*/#include /* 字符串处理字符串处理*/#define PROTOPORT 5188 /*缺省协议端口号缺省协议端口号*/extern int errno;char localhost =
48、“localhost”; /*缺省主机名缺省主机名*/ main(argc,argv)int argc;char *argv;struct hostent *ptrh; /* 指向主机列表中一个条目的指针指向主机列表中一个条目的指针 */struct sockaddr_in servaddr; /* 存放服务器端网络地址的结构存放服务器端网络地址的结构 */intsockfd; /* 客户端的套接字描述符客户端的套接字描述符 */intport; /* 服务器端套接字协议端口号服务器端套接字协议端口号*/char* host; /* 服务器主机名指针服务器主机名指针 */int n; /* 读
49、取的字符数读取的字符数 */char buf1000 ; /* 缓冲区,接收服务器发来的数据缓冲区,接收服务器发来的数据 */ memset(char*)& servaddr,0,sizeof(servaddr); /* 清空清空sockaddr结构结构 */servaddr.sin_family = AF_INET; /* 设置为因特网协议族设置为因特网协议族 */ /* 检查命令行参数,如果有,就抽取端口号。否则使用内定的缺省值检查命令行参数,如果有,就抽取端口号。否则使用内定的缺省值*/if (argc2) port = atoi(argv2); /* 如果指定了协议端口,就转换
50、成整数如果指定了协议端口,就转换成整数 */else port = PROTOPORT; /* 否则,使用缺省端口号否则,使用缺省端口号 */if (port0) /* 如果端口号是合法的数值,就将它装入网络地址结构如果端口号是合法的数值,就将它装入网络地址结构 */ servaddr.sin_port = htons(u_short)port);else /* 否则,打印错误信息并退出否则,打印错误信息并退出*/fprintf(stderr,”bad port number %sn”,argv2);exit(1); /* 检查主机参数并指定主机名检查主机参数并指定主机名 */if(argc1
51、)host = argv1; /* 如果指定了主机名参数,就使用它如果指定了主机名参数,就使用它 */elsehost = localhost; /* 否则,使用缺省值否则,使用缺省值 */ /* 将主机名转换成相应的将主机名转换成相应的IP地址并复制到地址并复制到servaddr 结构中结构中 */* 从服务器主机名得到相应的从服务器主机名得到相应的IP地址地址 */ptrh = gethostbyname( host ); if ( (char *)ptrh = null ) /* 检查主机名的有效性,无效则退出检查主机名的有效性,无效则退出 */ fprintf( stderr, ”in
52、valid host: %sn”, host ); exit(1);memcpy(&servaddr.sin_addr, ptrh-h_addr, ptrh-h_length ); Struct hostent char *h_name; char *h_aliases; int h_addrtype; int h_length; char *h_addr_list; ; /* 创建一个套接字创建一个套接字*/sockfd = SOCKET(AF_INET, SOCK_STREAM, 0);if (sockfd 0) fprintf(stderr, ”socket creation f
53、ailedn” ); exit(1);/* 请求连接到服务器请求连接到服务器 */if (connect( sockfd, (struct sockaddr *)& servaddr, sizeof(servaddr) 0) write(1,buf, n); n = recv( sockfd , buf, sizeof( buf ), 0 ); /* 关闭套接字关闭套接字*/closesocket( sockfd ); /* 终止客户程序终止客户程序*/exit(0); 4服务器实例代码服务器实例代码/*-* 程序:程序:server.c* 目的:目的: 分配一个套接字,然后反复执行如
54、下几步:分配一个套接字,然后反复执行如下几步:* (1) 等待客户的下一个连接等待客户的下一个连接* (2) 发送一个短消息给客户发送一个短消息给客户* (3) 关闭与客户的连接关闭与客户的连接* (4) 转向(转向(1)步)步* 命令行语法:命令行语法: server port * port 服务器端监听套接字使用的协议端口号服务器端监听套接字使用的协议端口号* 注意:注意: 端口号可选。如果未指定端口号,服务器使用端口号可选。如果未指定端口号,服务器使用PROTOPORT中指定的缺省中指定的缺省* 端口号端口号*-*/ #include #include #include #include
55、 #include #include #define PROTOPORT 5188 /* 监听套接字的缺省协议端口号监听套接字的缺省协议端口号 */#define QLEN 6 /* 监听套接字的请求队列大小监听套接字的请求队列大小 */int visits = 0; /* 对于客户连接的计数对于客户连接的计数*/ main(argc,argc)int argc;char* argv;struct hostent *ptrh; /* 指向主机列表中一个条目的指针指向主机列表中一个条目的指针 */struct sockaddr_in servaddr; /* 存放服务器网络地址的结构存放服务器网
56、络地址的结构 */struct sockaddr_in clientaddr; /* 存放客户网络地址的结构存放客户网络地址的结构 */int listenfd; /* 监听套接字描述符监听套接字描述符 */int clientfd; /* 响应套接字描述符响应套接字描述符 */int port; /* 协议端口号协议端口号 */int alen; /* 地址长度地址长度 */char buf1000; /* 供服务器发送字符串所用的缓冲区供服务器发送字符串所用的缓冲区 */ /* 清空清空sockaddr结构结构 */memset( (char*)& servaddr, 0, siz
57、eof(servaddr) ); servaddr.sin_family = AF_INET; /* 设置为因特网协议族设置为因特网协议族 */servaddr.sin_addr.s_addr = INADDR_ANY; /* 设置本地设置本地IP地址地址 */ /* 检查命令行参数,若已指定,则使用该端口号,否则使用缺省端口号检查命令行参数,若已指定,则使用该端口号,否则使用缺省端口号 */if (argc 1) port = atoi(argv1); /* 如果指定了端口号,就将它转换成整数如果指定了端口号,就将它转换成整数 */ else port = PROTOPORT; /* 否则,
58、使用缺省端口号否则,使用缺省端口号 */ if (port 0) /* 测试端口号是否合法测试端口号是否合法 */servaddr.sin_port=htons( (u_short)port );else /* 打印错误信息并退出打印错误信息并退出 */ fprintf( stderr, ”bad port number %sn”, argv1 ); exit(1); /* 创建一个用于监听的流式套接字创建一个用于监听的流式套接字 */listenfd = SOCKET(AF_INET,SOCK_STREAM,0);if (listenfd 0) fprintf( stderr, “socke
59、t creation failedn” ); exit(1); /* 将本地地址绑定到监听套接字将本地地址绑定到监听套接字*/if ( bind( listenfd, (struct sockaddr *)& servaddr, sizeof(servaddr) 0) fprintf(stderr, ”bind failedn” );exit(1); /* 开始监听,并指定监听套接字请求队列的长度开始监听,并指定监听套接字请求队列的长度 */if (listen(listenfd, QLEN) 0) fprintf(stderr, ”listen filedn” );exit(1);
60、/* 服务器主循环服务器主循环接受和处理来自客户端的连接请求接受和处理来自客户端的连接请求 */while(1) alen = sizeof(clientaddr); /* 接受客户端连接请求,并生成响应套接字接受客户端连接请求,并生成响应套接字 */ if(clientfd = accept( listenfd, (struct sockaddr *)& clientaddr, &alen) 0 ) fprintf( stderr, “accept failedn”); exit(1); visits+; /* 累加访问的客户数累加访问的客户数 */ sprintf( buf, “this server has been contacted %d time n”, visits ); se
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度出口企业出口货物报关单据与凭证管理合同3篇
- 二零二五年餐饮项目合伙经营合同范本3篇
- 2025年度智能化工厂租赁合同涉及土地使用权及配套设施4篇
- 二零二四年临时工劳动保障与劳动法实施合同3篇
- 专属2024版企业人力外包协议样本版B版
- 2024铝合金门窗生产与安装一体化工程合同3篇
- 2025年度企业级“师带徒”人才孵化项目合同3篇
- 专业劳务派遣协议样本2024版B版
- 街道党工委知识培训课件
- 2025年度商务办公空间租赁安全合同文本4篇
- 老年人视觉障碍护理
- 《脑梗塞的健康教育》课件
- 《请柬及邀请函》课件
- 中小银行上云趋势研究分析报告
- 辽宁省普通高中2024-2025学年高一上学期12月联合考试语文试题(含答案)
- 青海原子城的课程设计
- 常州大学《新媒体文案创作与传播》2023-2024学年第一学期期末试卷
- 麻醉苏醒期躁动患者护理
- 英语雅思8000词汇表
- 小学好词好句好段摘抄(8篇)
- JT-T-1059.1-2016交通一卡通移动支付技术规范第1部分:总则
评论
0/150
提交评论