《C#网络应用编程 第2版 教学课件 PPT 作者 马骏 第05章 TCP应用编程》由会员分享,可在线阅读,更多相关《C#网络应用编程 第2版 教学课件 PPT 作者 马骏 第05章 TCP应用编程(53页珍藏版)》请在金锄头文库上搜索。
1、第5章 TCP应用编程,5.1 TCP应用编程概述 5.2 利用同步TCP编写网络聊天程序 5.3 利用同步TCP编写网络游戏 5.4 异步TCP应用编程 5.5 异步TCP编程举例,第5章 TCP应用编程(续),本章教学目的 通过学习,使学生掌握涉及的知识点,能对TCP同步编程流程有深入认识,并熟悉异步TCP编程的基本概念和异步TCP应用编程的一般方法。 本章教学要求 (1)掌握TCP的特点、涉及到相关类、TCP应用编程的一般步骤以及怎样解决无消息边界问题 ; (2)掌握同步TCP编程的流程和使用方法。 (3)掌握异步设计模式、异步TCP应用编程的一般方法。 教学难点和重点 TCP应用编程的
2、一般步骤,如何开辟多线程与多个客户打交道,如何实现服务器和客户端相关功能。异步设计模式实现。,5.1 TCP应用编程概述,5.1.1 TCP简介 5.1.2 TcpListener类与TcpClient类 5.1.3 TCP应用编程的一般步骤 5.1.4 TCP的无消息边界问题,5.1.1 TCP简介,TCP是Transmission Control Protocol(传输控制协议)的简称,是TCP/IP体系中面向连接的运输层协议,在网络中提供全双工的和可靠的服务。 TCP最主要的特点: (1)是面向连接的传输层协议; (2)每个TCP连接只能有两个端点,而且只能一对一通信,不能一点对多点直接
3、通信。 (3)通过TCP连接传送的数据,能保证数据无差错、不丢失、不重复地准确到达接收方,并且保证各数据到达的顺序与数据发出的顺序相同。 (4)数据以字节流的方式传输。 (5)传输的数据无消息边界。,5.1.1 TCP简介(续),利用TCP开发应用程序时,.NET框架提供两种工作方式. (1)同步工作方式 指利用TCP编写的程序执行到发送、接收或监听语句时,在未完成工作前不再继续往下执行,即处于阻塞状态,直到该语句完成相应的工作后才继续执行下一条语句; (2)异步工作方式 异步工作方式是指程序执行到发送、接收或监听语句时,不论工作是否完成,都会继续往下执行。 例如:同步接收数据时,接收方执行到
4、接收语句后将处于阻塞方式,只有接收到对方发来的数据后才继续执行下一条语句;而如果采用异步工作方式,则接收方在执行到接收语句后,无论是否接收到对方发来的数据,程序都继续往下执行。,5.1.1 TCP简介(续),思考:这里的同步TCP和异步TCP与线程同步异步是否概念是否相同? 回答: (1)这里的同步TCP和异步TCP仅仅指工作方式,它和线程间的同步不是一个概念。 (2)线程间的同步指不同线程或其共享资源具有先后关联的关系,而同步TCP和异步TCP则仅仅指TCP编程中采用哪种工作方式,即是从执行到发送、接收或监听语句时,程序是否继续往下执行这个角度来说的。,5.1.2 TcpListener类与
5、TcpClient类,TcpListener类与TcpClient类两个类均封装了底层的套接字,并分别提供了对套接字进一步封装后的同步和异步操作的方法,降低了TCP应用编程的难度。 TcpListener类用于侦听和接受传入的连接请求。 TcpClient类用于提供本地主机和远程主机的连接信息。 注意,TcpListener和TcpClient只支持标准协议编程。如果希望编写非标准协议的程序,只能使用套接字来实现。,5.1.2 TcpListener类与TcpClient类(续),TcpListener类 TcpLISTener类在System.Net.Socket命名空间下。 常用的构造函数
6、有两种: TcpListener(IPEndPoint iep) TcpListener(IPAddress localAddr, int port) 举例: IPAddress ipAddress = Dns.Resolve(“localhost“).AddressList0; Try TcpListener tcpListener = new TcpListener(ipAddress, 1326); catch ( Exception e) Console.WriteLine( e.ToString(); ,5.1.2 TcpListener类与TcpClient类(续),在同步工作方式
7、下, TcpListener类常用的方法: Start 启动监听,构造函数为: public void Start(int backlog) 参数backlog为请求队列的最大长度,即最多允许的的客户端请求连接个数; Stop 关闭TcpListener并停止监听请求,构造函数为: public void Stop(); AcceptSocket 在同步阻塞方式下获取并返回一个用来接收和发送数据的Socket对象,同时从传入的连接队列中移除该客户端的连接请求。 AcceptTcpClient 在同步阻塞方式下获取并返回一个封装了Socket的TcpClient对象,同时从传入的连接队列中移除该
8、客户端的连接请求。,5.1.2 TcpListener类与TcpClient类(续),TcpClient类 TcpClient类在System.Net.Socket命名空间下。 主要用于编写客户端程序,且需要直接利用构造函数创建TcpClient对象。而服务器端程序中是通过TcpListener对象的AcceptTcpClient方法得到TcpClient对象的,所以不需要使用TcpClient类的构造函数来创建TcpClient对象。 构造函数有四种重载形式 TcpClient() TcpClient(AddressFamily family) TcpClient(IPEndPoint ie
9、p) TcpClient(string hostname,int port),5.1.2 TcpListener类与TcpClient类(续),(1)TcpClient() 该构造函数创建一个默认的TcpClient对象,并自动分配本机(客户端)IP地址和端口号。利用此构造函数创建对象后,还必须调用Connect方法与服务器建立连接。 例如: TcpClient tcpClient=new TcpClient(); tcpClient.Connect(““, 51888);,5.1.2 TcpListener类与TcpClient类(续),(2)TcpClient(AddressFamily
10、family) 该构造函数创建的TcpClient对象也能自动分配本机(客户端)IP地址和端口号,但是使用AddressFamily枚举指定使用哪种网络协议。创建该对象后,必须调用Connect方法与服务器建立连接。 例如: TcpClient tcpClient = new TcpClient(AddressFamily.InterNetwork); tcpClient.Connect(““, 51888);,5.1.2 TcpListener类与TcpClient类(续),(3)TcpClient(IPEndPoint iep) 该构造函数的参数iep指定本机(客户端)IP地址与端口号。当
11、客户端有一个以上的IP地址时,而且程序员希望直接指定使用的IP地址和端口号,可以使用这种方式。如果使用这种方式,必须调用Connect方法与服务器建立连接。例如: IPAddress address = Dns.GetHostAddresses(Dns.GetHostName(); IPEndPoint iep = new IPEndPoint(address0, 51888); TcpClient tcpClient = new TcpClient(iep); tcpClient.Connect(““, 51888);,5.1.2 TcpListener类与TcpClient类(续),(4)
12、TcpClient(string hostname,int port) 这是使用最方便的一种构造函数。参数中的hostname表示要连接到的远程主机的DNS名,port表示要连接到的远程主机的端口号。该构造函数会自动分配最合适的本地主机IP地址和端口号,并对DNS进行解析,然后与远程主机建立连接。例如: TcpClient tcpClient = new TcpClient(““, 51888); 它相当于: TcpClient tcpClient = new TcpClient(); tcpClient Connect(““,51888);,5.1.2 TcpListener类与TcpCli
13、ent类(续),TcpClient类的常用属性,5.1.2 TcpListener类与TcpClient类(续),TcpClient类的常用方法,5.1.2 TcpListener类与TcpClient类(续),TcpClient用法举例: TcpClient tcpClient = new TcpClient(); tcpClient.Connect(“contosoServer“, 11000); NetworkStream networkStream = tcpClient.GetStream(); networkStream.ReadTimeout = 10; byte bytes =
14、 new byte1024; networkStream.Read(bytes, 0, 1024); string data = Encoding.UTF8.GetString(bytes); networkStream.Close(); tcpClient.Close();,5.1.3 TCP应用编程的一般步骤,不论是多么复杂的TCP应用程序,网络通信的最基本前提就是客户端要先和服务器建立TCP连接,然后才可以在此基础上相互传输数据。由于服务器需要同时为多个客户端服务,因此程序相对复杂一些。 在服务器端,程序员需要编写程序不断地监听客户端是否有连接请求,一旦接受了客户端连接请求,即能识别是哪
15、个客户;而客户端与服务器连接则相对比较简单,只需要指定连接哪个服务器即可。一旦双方建立了连接并创建了对应的套接字,就可以相互传输数据了。在程序中,发送和接收数据的方法都是一样的,区别仅是方向不同。,5.1.3 TCP应用编程的一般步骤(续),编写服务器端程序的一般步骤为: 使用对套接字封装后的类,编写基于TCP的服务器端程序的 一般步骤为: (1)创建一个TcpListener对象,然后调用该对象的Start方法在指定的端口进行监听。 (2)在单独的线程中,循环调用AcceptTcpClient方法接受客户端的连接请求,并根据该方法的返回的结果得到与该客户端对应的TcpClient对象。 (3
16、)每得到一个新的TcpClient对象,就创建一个与该客户对应的线程,在线程中与对应的客户进行通信。 (4)根据传送信息的情况确定是否关闭与客户的连接。,5.1.3 TCP应用编程的一般步骤(续),编写客户端程序的一般步骤为: 使用对套接字封装后的类,编写基于TCP的客户端程序的一 般步骤如下: (1)利用TcpClient的构造函数创建一个TcpClient对象。 (2)使用Connect方法与服务器建立连接。 (3)利用TcpClient对象的GetStream方法得到网络流,然后利用该网络流与服务器进行数据传输。 (4)创建一个线程监听指定的端口,循环接收并处理服务器发送过来的信息。 (5)完成工作后,向服务器发送关闭信息,并关闭与服务器的连接。,5.1.4 TCP的无消息边界问题,在网络传输中,可能会出现发送方一次发送的消息与接收方一次接收的消息不一致的现象。这主要是因为TCP协议是字节流形式的、无消息边界的协议,由