书签 分享 收藏 举报 版权申诉 / 164
上传文档赚钱

类型《网络应用程序设计》课件第2章 基于TCP套接字的编程.ppt

  • 上传人(卖家):momomo
  • 文档编号:7894720
  • 上传时间:2024-09-01
  • 格式:PPT
  • 页数:164
  • 大小:1.08MB
  • 【下载声明】
    1. 本站全部试题类文档,若标题没写含答案,则无答案;标题注明含答案的文档,主观题也可能无答案。请谨慎下单,一旦售出,不予退换。
    2. 本站全部PPT文档均不含视频和音频,PPT中出现的音频或视频标识(或文字)仅表示流程,实际无音频或视频文件。请谨慎下单,一旦售出,不予退换。
    3. 本页资料《《网络应用程序设计》课件第2章 基于TCP套接字的编程.ppt》由用户(momomo)主动上传,其收益全归该用户。163文库仅提供信息存储空间,仅对该用户上传内容的表现方式做保护处理,对上传内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(点击联系客服),我们立即给予删除!
    4. 请根据预览情况,自愿下载本文。本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
    5. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007及以上版本和PDF阅读器,压缩文件请下载最新的WinRAR软件解压。
    配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    网络应用程序设计 网络应用程序设计课件第2章 基于TCP套接字的编程 网络 应用 程序设计 课件 基于 TCP 套接 编程
    资源描述:

    1、第第2章章 基于基于TCP套接字的编程套接字的编程 第第2章章 基于基于TCP套接字的编程套接字的编程 2.1 概述概述 2.2 套接字和套接字地址套接字和套接字地址2.3 基本套接字函数基本套接字函数2.4 高级套接字函数高级套接字函数2.5 多路复用多路复用2.6 网络字节传输顺序及主机字节顺序网络字节传输顺序及主机字节顺序2.7 DNS与域名访问与域名访问2.8 基于基于IP和域名的通信编程和域名的通信编程2.9 基于基于TCP套接字编程示例套接字编程示例习题习题第第2章章 基于基于TCP套接字的编程套接字的编程 2.1 概述20世纪80年代早期,美国国防高级研究计划局(ARPA,Adv

    2、anced Research Projects Agency)资助了加利福尼亚大学伯克利分校一个研究组,将TCP/IP 软件移植到UNIX操作系统中,并将结果提供给其他网点。作为项目的一部分,设计者们希望像访问文件一样去访问网络,因此,创建了一个接口,应用进程使用这个接口可以方便的进行通信。为了支持TCP/IP功能增加的新系统调用接口,形成了Berkeley Socket,这个系统被称为Berkeley UNIX或BSD UNIX(TCP/IP首次出现在BSD 4.1版本(release 4.1 of Berkeley Software Distribution)。由于许多计算机厂商都采用了B

    3、erkeley UNIX,Socket得到了迅速普及并被广泛使用。第第2章章 基于基于TCP套接字的编程套接字的编程 在UNIX系统中,网络应用编程界面有两类:UNIX BSD的套接字(socket)和UNIX System V的TLI。由于Sun公司采用了支持TCP/IP的UNIX BSD操作系统,使TCP/IP的应用有更大的发展,其网络应用编程接口套接字在网络软件中也被广泛应用,至今已引进到Linux和Windows系统中,成为开发网络应用软件的强有力工具,本章将详细讨论套接字的使用。Linux产生时,UNIX系统的网络功能已经相当成熟了,Linux网络的开发者选择了重新开发网络功能。在L

    4、inux网络代码开发的过程中,很多程序员做出了贡献。它提供的套接字有三种类型:流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM)及原始套接字(SOCK_RAW)。下面将详细介绍这些套接字的定义与应用。第第2章章 基于基于TCP套接字的编程套接字的编程 2.2 套接字和套接字地址 2.2.1 套接字套接字套接字是两个通信通道上的端节点。套接字函数可以用来产生通信信道,通过信道两个应用程序间可以传送数据。图2-1显示了利用套接字进行通信的示例。第第2章章 基于基于TCP套接字的编程套接字的编程 socketsocket函数应用程序应用程序函数网络协议管套管套ServerCl

    5、ient网络通信信道(a)(b)图2-1 套接字(a)套接字作为网络传输端点;(b)套接字对多种协议的支持第第2章章 基于基于TCP套接字的编程套接字的编程 套接字是信道的末端,当应用程序产生一个套接字后,套接字函数就返回所用文件的描述符。在这里,可以把支持虚电路服务的信道看做电话线,套接字就像一个电话。同样,可以把提供数据报服务的信道看做邮局系统,套接字看做信箱,人们可以向邮箱投递信件,信件通过邮局系统到达另一个信箱。应用程序利用套接字发数据报,数据报通过信道传向另一个套接字。在产生信道时,用户可以指定所用的传输提供者。例如,可以用TCP、UDP、XNS作传输提供者。第第2章章 基于基于TC

    6、P套接字的编程套接字的编程 Linux支持多种类型的套接字,也叫做套接字寻址簇,这是因为每种类型的套接字都有自己的寻址方法。Linux支持以下的套接字类型:UNIX UNIX域套接字INET Internet地址簇CP/IP协议支持通信IPX Novell IPXAPPLETALK Appletalk DDPX25 X25这些类型的套接字代表各种不同的连接服务。第第2章章 基于基于TCP套接字的编程套接字的编程 Linux的BSD 套接字支持下面的几种套接字类型:(1)流式(stream)。这种套接字提供了可靠的双向顺序数据流连接。它可以保证数据传输中的完整性、正确性和单一性。INET寻址簇中

    7、的TCP协议支持这种类型的套接字。(2)数据报(datagram)。这种类型的套接字也可以像流式套接字一样提供双向的数据传输,但它们不能保证传输的数据一定能够到达目的节点,也无法保证到达数据以正确的顺序到达以及数据的单一性、正确性。UDP协议支持这种类型的套接字。(3)原始(raw)。这种类型的套接字允许进程直接存取下层的协议。(4)可靠递送消息(reliable delivered messages)。这种套接字和数据报套接字一样,只能保证数据的到达。第第2章章 基于基于TCP套接字的编程套接字的编程(5)顺序数据包(sequenced packets)。这种套接字和流式套接字相同,但是它的

    8、数据包的大小是固定的。(6)数据包(packet)。这不是标准的BSD套接字类型,而是Linux中的一种扩展。它允许进程直接存取设备层的数据包。套接字的特点:(1)套接字没有与它相连的设备文件。应用程序可以用scoket()产生套接字,指定所用的信道类型。scoket()返回与所用信道末端相适应的文件描述符。(2)只要进程保存文件描述符,套接字就一直存在,直到没有进程打开文件描述符为止,套接字才被撤消。第第2章章 基于基于TCP套接字的编程套接字的编程(3)可以产生一个套接字,也可以同时产生一对套接字。如果产生一对套接字,则操作系统会自动在它们之间建立信道。如果只产生一个套接字,则用户程序就需

    9、要用套接字函数在该套接字与其他套接字间建立信道。因此,socket是一个工具,或者说是一种不可见控件,应用程序可以通过socket函数,来访问底层网络协议。第第2章章 基于基于TCP套接字的编程套接字的编程 2.2.2 套接字地址套接字地址 套接字接口利用传送提供者进行工作,不同的传送提供者有不同的地址,套接字接口允许指定任意类型的地址。Linux系统的套接字是一个通用的网络编程接口,它支持多种协议,每一种协议使用不同的套接字地址结构。Linux系统定义了一种通用的套接字地址结构,可以保持套接字函数调用参数的一致性。如下所示:struct sockaddr unsigned short sa_

    10、family;/*地址类型,AF_xxx*/char sa_data14;/*协议地址*/;第第2章章 基于基于TCP套接字的编程套接字的编程 其中:sa_family:保存协议标识符。AF_INET:代表TCP/IP协议簇。sa_data:保存具体的协议地址。TCP/IP协议簇的套接字地址也可以采用如下结构:#include#include第第2章章 基于基于TCP套接字的编程套接字的编程 struct in_addr _u32 s_addr;/*UINT类型*/struct sockaddr_in short int sin_family;/*地址类型:AF_XXX*/unsigned s

    11、hort int sin_port;/*端口号*/struct in_addr sin_addr;/*Internet 地址*/unsigned char sin_zero8;;第第2章章 基于基于TCP套接字的编程套接字的编程(3)sin_port和sin_addr必须保证以网络字节顺序传输。(4)IP地址作为参数传送时,注意addr.sin_addr与 a d d r.s i n _ a d d r.s _ a d d r 之 间 的 差 别。addr.sin_addr形式引用的是struct sin_addr结构类型的数据,addr.sin_addr.s_addr形式的引用是整数类型的数

    12、据。(5)由于和是Linux特有的头文件,为了能够保持代码的可移植性,在程序中不要直接包含它们,而与平台无关的、包含了它们。因此,程序中应该包含这两个头文件。第第2章章 基于基于TCP套接字的编程套接字的编程 2.2.3 IP地址的使用地址的使用在设置sockaddr_in类型的地址时,需要进行字符串形式的IP地址和二进制形式的地址间的转换,有如下一系列的函数可以处理IP地址的转换:#include#include#include int inet_aton(const char*cp,struct in_addr*inp);unsigned long int inet_addr(const

    13、char*cp);char*inet_ntoa(struct in_addr in);第第2章章 基于基于TCP套接字的编程套接字的编程 这几个函数将点分十进制数字形式表示的IP地址与32位的网络字节顺序的二进制形式的IP地址进行转换。例如,可以使用inet_addr()程序把诸如“192.168.5.10”形式的IP地址转化为无符号的整型数C0A8000A。函数inet_addr和inet_aton功能相同,函数inet_addr已过时,编程时应使用函数inet_aton。也可以调用inet_ntoa()把地址转换成数字和句点的形式:printf(%s,inet_ntoa(ina.sin_a

    14、ddr);这将会打印出IP地址。它返回的是一个指向字符串的指针。例如:第第2章章 基于基于TCP套接字的编程套接字的编程 char*a1,*a2;a1=inet_ntoa(ina1.sin_addr);/*这是192.92.129.1的二进制形式*/a2=inet_ntoa(ina2.sin_addr);/*这是132.241.5.10的二进制形式*/printf(address 1:%sn,a1);printf(address 2:%sn,a2);输出如下:address 1:192.92.129.1address 2:132.241.5.10第第2章章 基于基于TCP套接字的编程套接字的编

    15、程 2.3 基本套接字函数 在各种网络编程接口中,socket脱颖而出,越来越得到大家的重视,这是因为socket规范是一套开放的、支持多种协议的网络编程接口。经过不断发展和完善,并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成为网络编程的事实上的标准。下面给出套接字函数及其使用方法。1socket()在利用套接字进行网络通信时,进程要做的第一件事就是调用socket(),产生一个套接字,并指明将要使用的通信协议,如TCP、UDP、XNS、SPP等。第第2章章 基于基于TCP套接字的编程套接字的编程#include#include in

    16、t socket(int family,int type,int protocol);socket()返回一文件描述符,从应用的角度讲,该文件描述符是指通信信道的末端。如果调用失败,则返回-1。其中参数定义为:family:表示所用的协议是协议簇中的哪一个。协议簇是有相同地址格式的一组传送提供者。例如,TCP和UDP有同样的地址格式,因此它们属于同一协议簇。family的值可以为:第第2章章 基于基于TCP套接字的编程套接字的编程 AF_INET:TCP/IP协议集合。AF_UNIX:UNIX域协议簇,在本机的进程间通信时使用。AF_ISO:ISO协议簇。type:表示套接字类型:sock_S

    17、TREAM:提供虚电路服务的流套接字。sock_DGRAM:提供数据报服务的套接字。sock_RAW:原始套接字,只对Internet协议有效,可以用来直接访问IP协议。sock_SEQPACKET:有序分组套接字。sock_RDM:能可靠交付信息的数据报套接字。第第2章章 基于基于TCP套接字的编程套接字的编程 protocol:表示指定所用协议。对于大多数应用protocol都被设置为0,表示使用默认协议。但是,如果对给定的family及服务类型有多种协议可选,就须指定所用协议。例如,套接字要用TCP协议。因为TCP是TCP/IP协议集合中的一员,要用这个协议簇,应将family设为AF_

    18、INET。TCP/IP支持虚电路服务,故应将第二个参数types设为SOCK_STREAM。因为TCP是TCP/IP协议集合中惟一提供虚电路服务的传送提供者,所以protocol可以设为0。socket()调用为:int fd;fd=socket(AF_INET,SOCK_STREAM,0);第第2章章 基于基于TCP套接字的编程套接字的编程 又例如,用UDP协议,支持数据报服务。因为UDP属于TCP/IP协议簇,是TCP/IP协议集合中仅有的提供数据报服务的传输提供者,所以,protocol设置为0。该socket()调用为:int fd;fd=socket(AF_INET,SOCK_DGR

    19、AM,0);例如,产生一个套接字,访问TCP/IP协议集合的低层协议,可将套接字类型设为SOCK_RAW,这样允许访问低层协议,包括IP和ICMP。要让产生的套接字直接访问IP,protcol应设为IPPROTO_RAW。socket()调用为:int fdfd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);第第2章章 基于基于TCP套接字的编程套接字的编程 调用socket函数时,socket执行体将建立一个socket,并返回一个指向描述符表入口的socket句柄。实际上创建一个socket意味着为一个socket数据结构分配存储空间,如图2-2所示。第第2章章

    20、 基于基于TCP套接字的编程套接字的编程 协议簇服务类型本地IP地址远地IP地址本地协议端口号指向Internet结构远地协议端口号图2-2 socket数据结构第第2章章 基于基于TCP套接字的编程套接字的编程 表2-1给出了适应AF_INET及AF_UNIX协议簇的type及protocol的属性取值。第第2章章 基于基于TCP套接字的编程套接字的编程 表2-1 AF_INET 及 AF_UNIX协议簇的type及protocol的属性取值family type protocol 结 果 AF_INET SOCK_STREAM 0 TCP AF_INET SOCK_STREAM IPPRO

    21、TO_TCP TCP AF_INET SOCK_DGRAM 0 UDP AF_INET SOCK_DGRAM IPPROTO_UDP UDP AF_INET SOCK_RAW IPPROTO_ICMP ICMP AF_INET SOCK_STREAM IPPROTO_RAW IP AF_INET SOCK_SEQPACKET ANY 不用 AF_INET SOCK_RDM ANY 不用 AF_INET SOCK_STREAM 0 面向连接的循环服务提供者 AF_UNIX SOCK_DGRAM 0 面向无连接的循环服务提供者 AF_UNIX SOCK_RAW ANY 不用 AF_UNIX SOC

    22、K_SEQPACKET ANY 不用 AF_UNIX SOCK_RDM ANY 不用 第第2章章 基于基于TCP套接字的编程套接字的编程 2socketpair()socketpair()产生两个套接字,连接这两个套接字,然后返回相应的文件描述符,它也称为UNIX域套接字。其调用格式为:#include#include int socketpair(int family,int type,int protocol,int fd_array2);函数socketpair()返回两个套接字描述符:socket0和socket1,与管道pipe相似,只是socketpair()返回一对套接字描述符,

    23、而不是文件描述符。socketpair()返回的两个套接字描述符是双向的,而管道是单向的。第第2章章 基于基于TCP套接字的编程套接字的编程 Family、type、protocol参数含义与socket()函数一样,但是 socket()返回一个无连接套接字的文件描述符,socketpair()返回两个连接好的套接字。调用成功返回2,否则返回-1。family只能取值AF_UNIX,由于此系统调用仅用于UNIX支配协议,因此只有两种可用形式。一种是:int rc,fd_array2;rc=socketpair(AF_UNIX,SOCK_STREAM,0,fd_array);第第2章章 基于基

    24、于TCP套接字的编程套接字的编程 socketpair()用SVR4 面向连接的传输提供者之一产生一个通信信道。另一种是:int rc,fd_array2;rc=socketpair(AF_UNIX,SOCK_DGRAM,0,fd_array);这里,函数socketpair()用无连接的传输提供者产生一个通信信道。下面的函数可以用来生成一个域套接字间的通信信道。#include#include/*如果成功,则返回0,否则返回-1*/*用fd返回两个文件描述符*/第第2章章 基于基于TCP套接字的编程套接字的编程 int fd2;return(socketpair(AF_UNIX,SOCK_S

    25、TREAM,0,fd);3bind()调用socket函数创建套接字后,存在一个名字空间,但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字句柄联系起来,即将名字赋予套接字,以指定本地址中的协议,本地地址,本地端口。其调用格式如下:#include#include int=bind(int fd,struct sockaddr*addressp,int addrlen);第第2章章 基于基于TCP套接字的编程套接字的编程 其中:fd:由socket()函数返回的套接字描述符。addressp:向协议传送地址的指针,包含有关的地址信息:名称、端口和IP地址

    26、。addrlen:地址结构的字节数。bind()把传送地址与套接字连接在一起,调用成功返回 0,否则返回-1。地址的格式取决于与套接字相连的信道。例如,如果套接字的family设置为AF_UNIX,那么地址取sockaddr_un结构地址。服务器和客户机均可以调用函数bind绑定套接字地址,服务器往往绑定公认端口号,提供公共服务。第第2章章 基于基于TCP套接字的编程套接字的编程 处理地址绑定的程序片段如下:bzero(&servaddr,sizeof(servaddr);servaddr.sin_family=AF_INET;/*地址簇*/servaddr.sin_port=htons(se

    27、rverport);/*端口号*/servaddr.sin_addr.s_addr=htonl(INADDR_ANY);/*使用本机IP地址*/第第2章章 基于基于TCP套接字的编程套接字的编程 if (bind(sockfd,(struct sockaddr*)&servaddr,sizeof(struct sockaddr)0)perror(bind to serverport error);exit(1)第第2章章 基于基于TCP套接字的编程套接字的编程 注 意,在 给 网 络 地 址 赋 值 时,程 序 使 用 了INADDR_ANY,而不是确定的IP地址。这里INADDR_ANY的含

    28、义是任何网络设备接口。对于一台只有一个IP地址的主机,它就对应于它的IP地址。但是有的主机可能有多个网络接口,即多个网卡,并拥有多个IP地址,INADDR_ANY表示来自所有网络接口的相应传输层端口的连接请求,都由这个服务器进行处理。路由器就是典型的例子。一般来说,绑定操作具有以下几种组合方式,见表2-2。第第2章章 基于基于TCP套接字的编程套接字的编程 表2-2 绑定地址及端口号的设置方式应用程序 IP 地址 端口号 说 明 服务器 服务器 客户机 客户机 客户机 INADDR_ANY 本地 IP INADDR_ANY 本地 IP 本地 IP 非零值 非零值 非零值 非零值 零值 指定服务

    29、器为公认端口号 指定服务器 IP 地址和公认端口号 指定客户机的连接端口号 指定客户机的 IP 地址及连接端口号 指定客户机 IP 地址 第第2章章 基于基于TCP套接字的编程套接字的编程(1)服 务 器 的 套 接 字 设 定 公 认 端 口 号 和I N A D D R _ A N Y 地 址。服 务 器 的 套 接 字 设 定INADDR_ANY地址表明它要接收来自任何网络设备接口的客户连接请求,这是服务器常用的地址绑定方式。(2)服务器的套接字设定公认端口号和IP地址。如果服务器的套接字绑定公认端口号和具体IP地址,则表明服务器只接收来自这个IP地址的网络接口卡的客户机的连接请求。当服

    30、务器只有一个网络接口设备时,这种设置和(1)没有区别。当服务器有多个网络接口设备时,这种方法可以用来限制服务器的接收范围。第第2章章 基于基于TCP套接字的编程套接字的编程(3)客户机指定套接字地址中的端口号。当客户机调用connect函数请求TCP连接时,系统会自动为它选择一个未用端口号,并且用本地的IP地址设置套接字地址的相应项。因此,一般来说,客户机不用指定自己套接字地址的端口号。当客户机需要使用特定端口号时,如Linux系统中的rlogin命令,应当调用bind函数绑定一个未用的保留端口号。(4)客户机设置指定IP地址和连接端口号。当客户机绑定指定IP地址和连接端口号时,表示要用指定的

    31、网络设备接口和端口号进行通信。第第2章章 基于基于TCP套接字的编程套接字的编程(5)指定客户机的IP地址。客户机使用指定的网络设备接口进行通信,由系统为其选择一个未用的端口号。这种情况在系统具有多个网络设备接口时使用。4connect()客户进程在用socket()产生套接字后,用connect()将该套接字与服务器套接字相连接。#include#include int connect(int fd,struct sockaddr*addressp,int addrlen);第第2章章 基于基于TCP套接字的编程套接字的编程 其中:fa:是套接字描述符。addressp:套接字地址指针。ad

    32、drlen:地址结构的字节数。地址的格式取决于所用的信道。例如,如果信道的domain=AF_INET,那么用sockaddr_in结构保存地址;如果domain=AF_UNIX,那么用sockaddr_un结构保存地址。如果用数据报服务,则connect()在套接字与目的地址间建立简单的联系。系统在所有通过信道发送的数据报上均放上该地址。第第2章章 基于基于TCP套接字的编程套接字的编程 通常,在调用connect()前,客户应用程序应绑定套接字地址,提出连接请求的程序片段如下:bzero(&servaddr,sizeof(servaddr);servaddr.sin_family=AF_I

    33、NET;servaddr.sin_port=htons(serverport);if(inet_aton(192.168.0.2,&servaddr.sin_addr)0)perror(inet_aton error);exit(1);第第2章章 基于基于TCP套接字的编程套接字的编程 if(connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)0)perror(connect error);exit(1);.客户机一般不指定自己的端口号,而由系统为其选一个端口号,即自由端口。第第2章章 基于基于TCP套接字的编程套接字的编程 5

    34、listen()当服务器完成当前请求以前又发生多个服务请求时,例如,假设重复服务器处理完最近服务请求以前,客户程序试图与它相连,或者假设并行服务器在为最近服务请求建立好一个单独进程以前,客户程序请求和服务器建立连接。在这种情况下,服务器可以拒绝到来的服务请求。为了更好地处理这些问题,服务器可以使用listen()函数将所有的服务请求放在一个请求队列中排队,并尽快地处理这些请求。第第2章章 基于基于TCP套接字的编程套接字的编程 socket执行体建立一个输入请求队列,将到达的服务请求保存在此队列上,直到处理完它们为止,即listen()函数不仅使socket处于被动的侦听状态,同时告诉sock

    35、et执行体对此socket处理多个同时的服务请求。面向连接的服务器用该函数指明它愿意接收连接。其调用格式为:#include int listen(int fd,int qlen);第第2章章 基于基于TCP套接字的编程套接字的编程 其中:f d:套 接 字 的 文 件 描 述 符,套 接 字 只 能 是SOCK_STREAM,SOCK_SEQPACKET类型。qlen:连接请求队列长度。当一个连接请求到达时,被插入请求队列。服务器用accept()函数从队列中移走一个请求并响应这个请求。listen()函数不进入睡眠状态等待请求的到达,它只建立一等待队列,控制便返回应用程序。执行成功便返回0

    36、值,否则返回-1。在后面的例程中,将看到listen()函数的使用。第第2章章 基于基于TCP套接字的编程套接字的编程 6accept()面向连接的服务器执行了listen()函数后,执行accept()函数等待来自某一客户进程的实际连接请求。然后进入睡眠状态,等待客户机的连接请求。当服务请求到达accept()函数监视的socket时,socket执行体将自动建立一个新的socket,并将此socket和客户进程连接起来。收到服务请求的初始socket仍具有设定的地址,因此,它可以继续接收到达的服务请求。下面是accept()函数的声明:#include#include int accept

    37、(int fd,sockaddr*addressp,int*addrlen);第第2章章 基于基于TCP套接字的编程套接字的编程 参数addressp 用于返回所连接的对等进程的地址,里面存储着远程连接的计算机信息(比如远程计算机的IP地址和端口)。参数addrlen是一个本地的整型数值,由协议执行体设置它的值。一般情况下,调用者把该值设置为缓冲区的大小,该调用也可设置成sockaddr 的结构大小,在系统调用返回时将此值改变成为存放在缓冲区中的实际字节数。第第2章章 基于基于TCP套接字的编程套接字的编程 accept()从队列上取出第一个连接请求,建立一个与参数fd相同特性的套接字。参数f

    38、d所指套接字类型可以是SOCK_STREAM或SOCK_SEQPACKET。如果采用同步通信模式,则accept()将等待连接请求的到达。在连接请求到达时,accept()产生一个新套接字,并对其行连接,返回新套接字的文件描述符。此刻用所产生的新套接字与客户应用进行通信,而用原来的套接字接收其他连接请求。第第2章章 基于基于TCP套接字的编程套接字的编程 如果调用accept()时队列上无连接请求,那么此调用在一个请求到达前阻塞调用者的运行,accept()返回-1,errno置为EWOULDBLOCK,指出无连接请求到达。7read()及write()read()函数和write()函数是用

    39、来接收和发送数据的两个函数。read()函数用于从套接字缓冲区读取数据,write()函数用于往套接字缓冲区写数据,它们的定义分别如下:int read(int fd,char*buf,int len);int write(int fd,char*buf,int len);第第2章章 基于基于TCP套接字的编程套接字的编程 参数fd是我们要进行读写操作的连接套接字描述符(由connect()函数或accept()函数返回),参数buf是用于存放欲接收或待发送数据的应用缓冲区,参数len指定了欲发送或者接收的数据字节数。对于read()函数,调用后将从套接字接收缓冲区中读取len字节的数据,如果

    40、函数成功返回,返回值将是实际读取数据的字节数,见表2-3。第第2章章 基于基于TCP套接字的编程套接字的编程 表2-3 read()函数返回值及其意义返回值 n 意 义 无数据 阻塞 n=len 读出 len 个字节 n0 and nlen 读出 n 个字节 n=0 读通道已关闭 n0)/*读出rc个字节*/return rc;else if(rc=0)/*读通道已关闭*/第第2章章 基于基于TCP套接字的编程套接字的编程 close(fd);return 0;else if(errno=EINTR)/*由读中断引起错误 */第第2章章 基于基于TCP套接字的编程套接字的编程 else pri

    41、ntf(stderr,Read error);close(fd);return-1;当read用于套接字读取时,应分析read()函数的返回值,特别是返回值小于等于零的情况,当返回值小于零时并非表示真正出错。第第2章章 基于基于TCP套接字的编程套接字的编程 (1)返回值大于零,套接字接收缓冲区接收到数据,返回值表示读取的数据字节数。(2)返回值等于零,并且以后这个套接字读操作返回值均为0,表示对方已发送完所有的数据。这和读文件时遇到文件结束符的情况相似。(3)如果read错误返回,且错误号为EINTR,则是指进程阻塞过程中接收到了信号,并非真正出错,以后可以继续利用该套接字读数据。(4)当r

    42、ead错误返回,且错误号为ECONNRESET时,表示TCP协议接收到RST数据段,连接出现了某种错误,并且以后所有在这个套接字上的读操作均返回错误。第第2章章 基于基于TCP套接字的编程套接字的编程 2)函数write_allint write_all(int fd,char*buf,int nBytes);for(;)wc=write(sockfd,buf,nBytes);if(wc0)/*写入成功*/return wc;第第2章章 基于基于TCP套接字的编程套接字的编程 else if(errno=EINTR)/*由中断引起错误*/else printf(stderr,Write err

    43、or);close(sockfd);return-1;第第2章章 基于基于TCP套接字的编程套接字的编程 同读操作类似,write操作也要按返回值分情况处理。(1)TCP协议接收到RST数据段。当接收方已关闭连接之后,如果继续向这个套接字上发送数据将导致对方的TCP协议返回RST数据段,函数wirte返回错误,错误类型为EPIPE,并且以后所有这个套接字上的写操作均以错误返回。(2)进程阻塞期间接收到信号。如果进程接收到信号,则函数wirte()返回错误,错误类型为EINTR。这并不是真正出现了错误,可以继续利用该套接字发送数据。以上两程序段分别实现对缓存内数据的读(read)、写(write

    44、)操作,较为详细的说明了read()和write()两个函数的调用方法和出错类型。第第2章章 基于基于TCP套接字的编程套接字的编程 2.4 高级套接字函数高级套接字函数1send()及sendto()send()与sendto()均可用来通过信道发送数据。send()可用于流式或数据报通信信道。在采用数据报传送方式时,应利用connect()函数给出所连接的套接字地址。sendto()函数用于无连接的数据报发送,发送数据报时须指出数据要发送到的目的地址。由于这个地址是与协议相关的,因此不同协议对应的地址也不同,其长度由addrlen指定。sendto()基本上用于无连接套接字。它们的功能与w

    45、rite系统调用相似。其调用方式如下:第第2章章 基于基于TCP套接字的编程套接字的编程#include#include int send(int fd,char*buf,int len,int flags);int sendto(int fd,char*buf,int len,int flags,struct sockaddr*toaddr,int addrlen);其中,参数定义为:fd:套接字的文件描述符。buf:数据缓冲区。len:数据缓冲区字节数。toaddr:存放数据要发送的目的套接字地址。第第2章章 基于基于TCP套接字的编程套接字的编程 addrlen:地址的字节数。flags

    46、:取值为0时,send()的功能与wrirte()相同;为M S G _ O O B 时,发 送 连 接 带 外 数 据(O O B,Out_Of_Band);为MSG_DONTWAIT时,如果套接字缓冲区中没有足够空间,则进程不阻塞等待;MSG_DONTROULE:旁路路由选择。2recv()及recvfrom()recv()及recvfrom()功能类似于read()系统调用。它们都是用来从连接的套接字上读数据,可以用在client或server上的应用中。它们的调用格式为:第第2章章 基于基于TCP套接字的编程套接字的编程#include#include int recv(int fd,

    47、char*buf,int len,int flags);int recvfrom(int fd,char*buf,int len,int flags,struct sockaddr*fromaddr,int addrlen);其中,参数定义如下:fd:套接字的文件描述符。buf:数据缓冲区。第第2章章 基于基于TCP套接字的编程套接字的编程 len:数据缓冲区字节数。fromaddr:发送数据的套接字地址。addrlen:地址的字节数。flags:取值为:0:功能与read()相同;MSG_OOB:接收连接外数据;MSG_WAITALL:如果套接字缓冲区中没有足够空间,则进程不阻塞等待;MSG

    48、_PEEK:将数据放置于缓冲区中,该数据使用后并不马上被取消,因此,下 一 个 读 操 作 将 会 读 到 同 样 的 数 据;MSG_DONTROUTE:发送数据时,不需要查看路由表。第第2章章 基于基于TCP套接字的编程套接字的编程 返回值:按同步方式工作时,等待数据的到达;按异步方式工作时,如果套接字中无数据,则设置errno为EWOULDBLOCK,并返回-1,表示数据未准备好。只返回-1时,表示出错。3sendmsg()及recvmsg()sendmsg()用来发送数据,包含sendto()的功能。除此之外,它还可以规格化数据以及发送被中断了的数据,与sendto()一样,可以用于虚

    49、电路和数据报方式。recvmsg()用于接收sendmsg()发送的数据。它们的使用方式为:#include#include#include 第第2章章 基于基于TCP套接字的编程套接字的编程 struct iovec caddr_t iov_base;/*缓冲区的起始地址*/int iov_len;/*缓冲区的字节数*/;struct msghdr caddr_t msg_name;/*目的套接字地址*/第第2章章 基于基于TCP套接字的编程套接字的编程 int msg_namelen;/*地址的字节数*/struct iovec*msg_iov;/*包含信息的数组*/int msg_iov

    50、len;/*结构数组的成员量*/caddr_t msg_accrights;/*访问权限*/int msg_accrightslen;第第2章章 基于基于TCP套接字的编程套接字的编程 函数定义:int sendmsg(int fd,struct msghdr*msgp,int flags);int recvmsg(int fd,struct msghdr*msgp,int flags);其中,结构iovec保存信息数据。msg_name和msg_namelen是发送信息的套接字地址。msg_iov由sendmsg()函数填写结构 iovec 的内容。第第2章章 基于基于TCP套接字的编程套接

    展开阅读全文
    提示  163文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:《网络应用程序设计》课件第2章 基于TCP套接字的编程.ppt
    链接地址:https://www.163wenku.com/p-7894720.html

    Copyright@ 2017-2037 Www.163WenKu.Com  网站版权所有  |  资源地图   
    IPC备案号:蜀ICP备2021032737号  | 川公网安备 51099002000191号


    侵权投诉QQ:3464097650  资料上传QQ:3464097650
       


    【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。

    163文库