WIN32汇编语言教程:第16章 TCP/IP和网络通信 · 16.3 TCP协议编程(1)

介绍了WinSock编程的一般流程和常用函数以后,现在来看如何使用流套接字传输数据。

16.3.1 TCP协议简介

1. TCP协议的特征

TCP协议是一种传输层上的协议,它提供一种面向连接的、可靠的字节流服务。

面向连接意味着两个使用TCP协议的应用程序在开始传输数据之前必须先建立一个连接。其含义就是由一方首先向另一方发送请求信息,等对方确认以后才能开始通信。这一过程与打电话很相似,一方先拨号振铃,等待对方摘机后才开始对话,如果对端没有程序响应,那就像没有人接电话一样,通信是无法开始的。另外,面向连接意味着TCP协议不能用于广播,即一方不能用一个套接字同时向多方发送数据。

TCP通信是可靠的,它采用超时以及重传机制来保证不丢失数据。当一个TCP发送一个数据包后,它将启动一个定时器,等待对端确认收到这个包,如果在指定的时间内没有得到确认,它将重发这个数据包。而接收数据包的时候,它将发送一个确认,如果检测发现数据包的校验和有错,TCP协议丢弃这个数据包并且不发送确认,那么对端会因为超时而重新发送这个数据包。

数据包在传输的时候会通过多个路由器,不同的数据包到达终点前经过的路由器可能是不同的,因此所花的时间也是不同的,这就可能造成后发的数据先到的情况,TCP协议在TCP首部保存数据包序号,如果有必要,它将对收到的数据进行重新排序,并将收到的数据以正确的顺序交给应用层。

接收方收到的IP报文段也可能重复,原因之一是在发送和确认之间还有个时差,发送方可能因为接收方的确认信息还在路上就发生超时而重发数据,这时接收方收到的数据包就会发生重复,对于这种情况,TCP的接收端会丢弃重复的数据。

TCP还提供流量控制机制,发送方可以根据接收方应答的时间和速率适当调整自己的数据发送速度,这样可以防止速度较快的主机使速度较慢主机的接收缓冲区溢出。

TCP协议的工作过程也和打电话的过程很相似。当一方滔滔不绝地讲话时,需要另一方偶尔回复“是的”、“嗯”之类的短语来确认,如果有一段时间没有听到对方的简短确认,发言方就会停下来问一句“你在听吗”。当另一方没有听清楚某句话的时候,他会说:“你刚才说什么,我没有听清楚”,这样发言方会复述前面的句子。如果一方讲得太快,另一方会要求他适当放慢速度。TCP协议实现的机制就与此类似。

2. TCP程序的客户机/服务器模型

从TCP协议的特征可以看出通信双方的工作方式必然是不同的,这种工作方式的不同可以用客户机/服务器模型(Client/Server或C/S)来描述,通信的发起端被称为客户机(Client,也称为工作站端或者客户端),通信的等待方被称为服务器(Server),图16.8显示了两者工作方式的不同,图中的括号内显示了各步骤使用的WinSock函数。


图16.8 TCP服务器和客户机模型

就像打电话一样,A对B说:“某某时候Call我”,那么B给A打电话的过程就可以用这种客户机/服务器模型来描述。为了等待B的电话,A必须在双方约定的某个特定的电话旁边等待,否则B将不知道如何Call他。“特定的电话”意味着服务器端的地址必须是特定的,所以服务器端的套接字必须首先使用bind函数绑定到指定的IP地址和端口上。“等待”意味着服务器必须随时监听客户端的连接动作,所以套接字绑定地址后必须使用listen函数进入监听状态。而对于B来说,他可以在任何时刻从任何电话给A打电话。由此可见,客户端使用的套接字并不需要绑定过程,让系统自动指定任意值并不影响它向服务器端发起连接。

客户端可以随时使用connect函数连接到服务器,服务器检测到这个连接后,需要使用accept函数接受这个连接,当服务器接受连接后,一个稳定的连接就建立了,双方就可以开始互相通过send和recv函数收发数据了。

下面用两个互相配合的例子—聊天室服务器和客户端例子来演示如何用WinSock接口来实现这个模型。当在一台计算机上运行聊天室服务器程序以后,网络上可以有多个聊天客户端程序同时连接到服务器,当任意一个客户端发出一句话后,服务器将它转发到所有在线的客户端,这样所有的客户端就可以通过服务器进行聊天。

16.3.2 TCP聊天室例子——客户端

TCP聊天室的例子代码放在所附光盘的Chapter15\Chat-TCP目录中,包括服务器端代码和客户端代码。编译链接后执行将产生如图16.9所示的界面,图中后面的窗口是服务器端的界面,对话框中的编辑框中将显示所有客户端的对话内容,对话框最下面显示当前有多少个客户端在线。

图中前面的窗口是客户端的界面,使用时必须首先输入服务器IP地址并进行连接,当连接成功后,在下面的输入框中输入聊天内容并单击“发送”键,就可以将它发送给服务器端程序,服务器端会将它转发给所有的在线客户端。


图16.9 TCP聊天室例子的运行界面

先来看相对比较简单的客户端程序,客户端代码由Client.asm和Client.rc文件组成。Client.rc文件定义了图16.9前端的窗口,内容如下:

#include      <resource.h>

#define ICO_MAIN          1000

#define DLG_MAIN          2000

#define IDC_SERVER    2001

#define IDC_CONNECT    2002

#define IDC_INFO          2003

#define IDC_TEXT          2004

//####################################################################

ICO_MAIN      icon              "Main.ico"

//####################################################################

DLG_MAIN DIALOG 94, 81, 245, 155

STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU

CAPTION "TCP聊天-客户端"

FONT 9, "宋体"

{

 LTEXT "服务器IP地址:", -1, 6, 7, 57, 8

 EDITTEXT IDC_SERVER, 63, 5, 116, 12

 PUSHBUTTON "连接(&C)", IDC_CONNECT, 186, 4, 56, 14

 EDITTEXT IDC_INFO, 4, 22, 237, 110, ES_MULTILINE | ES_AUTOVSCROLL

| ES_AUTOHSCROLL | ES_READONLY | WS_BORDER | WS_VSCROLL | WS_TABSTOP

 LTEXT "输入", -1, 6, 140, 19, 8

 EDITTEXT IDC_TEXT, 28, 138, 150, 12, ES_AUTOHSCROLL | WS_DISABLED

| WS_BORDER | WS_TABSTOP

 DEFPUSHBUTTON "发送(&S)", IDOK, 185, 137, 56, 14, BS_DEFPUSHBUTTON

| WS_DISABLED | WS_TABSTOP

}

上页:第16章 TCP/IP和网络通信 · 16.2 WinSock接口(4) 下页:第16章 TCP/IP和网络通信 · 16.3 TCP协议编程(2)

第16章 TCP/IP和网络通信

版权所有 © 中山市飞娥软件工作室 证书:粤ICP备09170368号