计算机网络课件第4章TCP程序设计

上传人:小萌新****ao 文档编号:367672514 上传时间:2023-11-10 格式:PPT 页数:91 大小:499.50KB
返回 下载 相关 举报
计算机网络课件第4章TCP程序设计_第1页
第1页 / 共91页
计算机网络课件第4章TCP程序设计_第2页
第2页 / 共91页
计算机网络课件第4章TCP程序设计_第3页
第3页 / 共91页
计算机网络课件第4章TCP程序设计_第4页
第4页 / 共91页
计算机网络课件第4章TCP程序设计_第5页
第5页 / 共91页
点击查看更多>>
资源描述

《计算机网络课件第4章TCP程序设计》由会员分享,可在线阅读,更多相关《计算机网络课件第4章TCP程序设计(91页珍藏版)》请在金锄头文库上搜索。

1、第4章TCP程序设计TCP协议是网络应用中使用最为广泛的一种传输层协议,例如文件传输协议(FTP)、超文本传输协议(HTTP)、接收邮件的POP3协议等,均使用了TCP协议。TCP为应用程序提供可靠的数据传输服务,是操作系统的一个重要组成部分,但是,对程序员来说TCP是不可见的,程序员无法直接在程序中使用TCP,必须通过套接字编程接口才能使用。Winsock是通过流式套接字(SOCK_STREAM)来提供TCP服务的。4.1.1TCP客户端和服务器端的交互过程n流式套接字使用的传输协议是TCP协议,TCP协议是一种面向连接的协议,它在传输数据之前必须先建立连接,通信完成后还需要释放链接。n连接

2、的建立和释放是由通信双方相互协作共同完成的。n主动发起连接建立的一端被称为“客户”,被动接收连接请求的一端被称为“服务器”。通常,TCP服务器大都可以同时与多个客户保持连接,此时,服务器被称为并发服务器。通信过程中,服务器端至少会有两个套接字,一个被称为监听套接字(或侦听套接字),由服务器程序调用socket()函数创建,用于等待客户连接请求的到来;其余套接字则是在建立连接时由系统创建,称为已连接套接字,每当监听套接字收到一个客户连接请求,系统就会创建一个新的已连接套接字与客户建立连接,并且以后与客户之间的所有数据交换也必须使用这个已连接套接字。服务器端与客户端程序流程服务器端:(1)调用so

3、cket函数建立一个套接字,用于监听;(2)调用bind函数为监听套接字绑定端口号和IP地址;(3)调用listen函数,设置套接字处于监听状态;(4)反复执行以下各步:用accept函数等待客户连接到来请求到来,有到来则创建一个新的套接字来建立起与客户机之间的通信连接;使用recv函数和send函数利用新建的连接与客户端通信;通信完毕调用closesocket函数关闭新建连接;(5)调用closesocket函数关闭监听套接字,程序结束。客户机(1)用socket函数建立一个套接字,设定服务器的IP和端口;(2)调用connect函数连接远程计算机指定的端口;(3)利用新建的连接与服务器通信

4、;(4)通信完毕调用closesocket函数关闭连接。需要注意,服务器程序和客户程序所创建的套接字的用处是不同的服务器创建的套接字是监听套接字,并不用于数据收发。用于收发数据的套接字由accept()函数接收连接请求时创建。客户端创建的套接字则有两方面用途,一是向服务器发送连接建立请求,二是用于进行客户端的数据收发。1.创建套接字socket()函数SOCKETsocket(intaf,inttype,intprotocol);用于创建一个套接字。af:标识一个地址家族,通常为AF_INET。type:标识套接字类型,SOCK_STREAM表示流式套字;SOCK_DGRAM表示数据报套接字;

5、SOCK_RAW表示原始套接字。protocol:标识一个特殊的协议被用于这个套接字,通常为0,表示采用默认的TCP/IP协议相关套接字函数的使用方法socket()函数返回的套接字描述符的类型符SOCKET,它是Winsock中专门定义的一种新的数据类型,其定义为typedefu_intSOCKET;是一个无符号整型数。创建套接字失败返回的常量INVALID_SOCKET的定义如下:#defineINVALID_SOCKET(SOCKET)0是各二进制位全为1的一个无符号整数。不难看出,合法的套接字描述符的取值可以是0INVALID_SOCKET-1之间的任何值。/建立一个socketsoc

6、k_server=socket(AF_INET,SOCK_STREAM,0);if(sock_server=INVALID_SOCKET)/socket建立失败interrno=WSAGetLastError();cout创建套接字失败!错误代码:errnoendl;return0;else/socket建立成功coutsocketcreated.sock_serverendl;2.绑定地址bind函数socket()函数在创建套接字时并没有为创建的套接字分配地址,因此服务器软件在创建了监听套接字之后,需要调用bind函数为其指定本机地址、协议和端口号。intbind(SOCKETs,stru

7、ctsockaddr*name,intnamelen);将套接字绑定到一个已知的地址上。如果函数执行成功,返回值为0,否则为SOCKET_ERROR。s:是一个套接字。name:是一个sockaddr结构指针,该结构中包含了要绑定的地址和端口号。namelen:确定name缓冲区的长度。该函数要绑定的地址是由一个sockaddr类型的指针参数指定的,sockaddr结构的定义如下struct sockaddr u_short sa_family;/地址族 char sa_data14;/协议地址 可以看出,直接向该结构的变量中填充地址信息并不方便。事实上,在编程时可以先定义一个sockaddr

8、_in结构的变量,在填充完地址信息后再将该结构变量的地址强制转换为sockaddr类型的指针来使用。struct sockaddr_inshort sin_family;/AF_INET u_short sin_port;/16位端口号,网络字节顺序 struct in_addr sin_addr;/32位IP地址,网络字节顺序char sin_zero8;/保留/绑定绑定IPIP端口端口struct sockaddr_instruct sockaddr_in addr;addr.sin_family=AF_INET;addr.sin_port=htons(PORT);addr.sin_add

9、r.s_addr=htonl(INADDR_ANY);/允许套接字使允许套接字使用本机的任何用本机的任何IPIPif(bind(sock_server,(LPSOCKADDR)(LPSOCKADDR)&addr,sizeof(addr)!=0)printf(邦定失败!n);return 0;强制类型转换为强制类型转换为struct sockaddr*struct sockaddr*将IP地址设置为INADDR_ANY,是表示该套接字的IP地址由系统自动指定,如果你希望自己明确指定一个IP地址,则只要将INADDR_ANY替换为一个无符号整数表示的32位IP地址则可。如果你希望由系统自动给你分配

10、一个端口号,则只要将PORT定义为0则可。否则,PORT应定义为一个用16位无符号整数表示的可用端口号。注意:客户端的套接字可以不用绑定地址,当客户端程序调用connect()函数与服务器建立连接时,系统会为套接字自动选择一个IP地址和临时端口号。事实上服务器端的监听套接字不绑定地址也不会出现明显错误,因为当服务器调用listen()时,系统也会为监听套接字分配IP地址和临时TCP端口号,不过由于临时端口号很难被客户知晓从而导致客户无法访问服务器,因此服务器端需要绑定指定的地址。3.开始监听listen()函数listen()函数只能由服务器端使用,而且只适用于流式套接字,listen()函数

11、用于将套接字置为监听模式。intlisten(SOCKETs,intbacklog);s:套接字。backlog:表示等待连接的最大队列长度。例,若设置backlog为3,当同时收到4个客户连接请求时,则前3个客户连接请求会放置在等待队列中,第4个客户端会得到错误信息。该参数值通常设置为常量SOMAXCONN,表示将连接等待队列的最大长度值设为一个最大的“合理”值,该值有底层开发者指定,WinSock2中,该值为5。if(listen(sock_server,if(listen(sock_server,SOMAXCONN)!=0)!=0)coutlistencoutlisten函数调用失败!函

12、数调用失败!n;n;return 0;return 0;4.客户端发送连接请求connect()函数intconnect(SOCKETs,conststructsockaddr*name,intnamelen);s:标识一个套接字。connect函数用于发送一个连接请求。若成功则返回0,否则为SOCKET_ERROR。用户可以通过WSAGetLastError得到其错误描述。name:套接字s想要连接的主机地址和端口号。namelen:name缓冲区的长度。/连接服务器 struct sockaddr_in server_addr;memset(void*)&server_addr,0,add

13、r_len);server_addr.sin_family=AF_INET;server_addr.sin_port=htons(PORT);server_addr.sin_addr.s_addr=inet_addr(“127.0.0.1”)if(connect(sock_client,(LPSOCKADDR)&server_addr,addr_len)!=0)printf(连接失败n);return 0;5.接收连接请求accpet()函数SOCKETaccept(SOCKETs,structsockaddr*addr,intFAR*addrlen);s:是一个套接字,它应处于监听状态。ad

14、dr:是一个sockaddr_in结构指针,包含一组客户端的端口号、IP地址等信息。addrlen:用于接收参数addr的长度。用于接受客户端的连接请求。accept()函数返回一个已建立连接的新的套接字的描述符,即已连接套接字的描述符,服务器与本连接所对应客户端的所有后续通信,都应使用该套接字。原来的监听套接字仍然处于监听状态,可以继续接受其他客户的连接请求。如果发生错误,将返回INVALID_SOCKET默认情况下,如果调用accept()时还没有客户的连接请求到达,accept()将不会返回,进程将阻塞,直到有客户与服务器建立了连接才会返回。intaddr_len=sizeof(clie

15、nt_addr)SOCKETnewsock=accept(sock_server,(LPSOCKADDR)&client_addr,&addr_len);if(newsock=INVALID_SOCKET)coutaccept()函数调用失败!错误代码:;coutWSAGetLastError()endl;6.发送数据send()函数intsend(SOCKETs,constchar*buf,intlen,intflags);用于在已经建立连接的套接字上发送数据。s:标识一个套接字buf:是存放要发送数据的缓冲区len:标识缓冲区长度flags:用于控制数据发送的方式,通常取0,表示正常发送数

16、据;如果取值为宏MSG_DONTROUT,则表示目标主机就在本地网络中,也就是与本机在同一个IP网段上,数据分组无须路由可直接交付目的主机,如果传输协议的实现不支持该选项则忽略该标志;如果该参数取值为宏MSG_OOB,则表示数据将按带外数据发送。带外数据(OutOfBand,OOB)本义是指那些使用与普通数据不同的另外的信道传送的一些特殊数据。带外数据一般都是一些重要的数据,通信协议通常能将这些数据快速地发送到对方。TCP协议试图通过紧急数据机制来实现带外数据的功能,但紧急数据并不是真正意义上的带外数据,因为TCP并没有真正开辟一个新的信道进行数据传输,而是将这些数据放在普通的数据流中一起传输。现在,TCP的带外数据功能基本已经是废弃的功能了。2011年发表的有关TCP的紧急数据的因特网标准RFC6093就强烈建议,新的应用不要再使用紧急数据机制。OOB数据(7)recv函数intrecv(SOCKETs,char*buf,intlen,intflags);用于从连接的套接字中返回数据。该函数执行成功返回实际从套接字s读入到buf中的字节数。连接终止则返回0;否则返回SOCKET_ER

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号