第3章 TCP编程_第1页
第3章 TCP编程_第2页
第3章 TCP编程_第3页
第3章 TCP编程_第4页
第3章 TCP编程_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、3.1 TCP简介简介3.2 同步同步与异步与异步3.3 C#中的中的TCP编程类编程类3.4 TCP基础编程的一般步骤基础编程的一般步骤3.5 同步同步TCP编程编程3.6异步异步TCP编程编程3.7 两种两种TCP程序的区别程序的区别3.1.1 TCP的工作过程的工作过程1. 连接的建立连接的建立TCP协议通过三个报文段完成类似电话呼叫的连接建立过程,这个过程称为三次握手(three-way handshake),如图3.1所示。2. 传输数据传输数据一旦通信双方建立了TCP连接,连接中的任何一方都能向对方发送数据和接收对方发来的数据。TCP协议负责把用户数据(字节流)按一定的格式和长度组

2、成多个数据报进行发送,并在接收到数据报之后按分解顺序重新组装和恢复用户数据。利用TCP传输数据时,数据是以字节流的形式进行传输的。3. 连接的终止连接的终止建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。具体过程如图3.2所示。TCP最主要的特点如下。(1)是面向连接的协议。(2)端到端的通信。每个TCP连接只能有两个端点,而且只能一对一通信,不能一点对多点直接通信。(3)高可靠性。通过TCP连接传送的数据,能保证数据无差错、不丢失、不重复地准确到达接收方,并且保证各数据到达的顺序与其发出的顺序相同。(4)全双工方式传输。(5)数据以

3、字节流的方式传输。(6)传输的数据无消息边界。在TCP工作时,底层Socket详细的通信流程如图3.3所示。同步工作方式是指利用TCP编写的程序执行到监听或接收语句时,在未完成工作(侦听到连接请求或收到对方发来的数据)前不再继续往下执行,线程处于阻塞状态,直到该语句完成相应的工作后才继续执行下一条语句。异步工作方式是指程序执行到监听或接收语句时,不论工作是否完成,都会继续往下执行。3.3.1 TcpListener类类TcpListener类用于监听和接收传入的连接请求。该类的构造函数常用的有以下两种重载形式: TcpListener(IPEndPoint iep) TcpListener(I

4、PAddress localAddr, int port)在同步工作方式下,对应有:(1)Start方法。(2)Stop方法。(3)AcceptSocket方法。(4)AcceptTcpClient方法。表3-1列出了TcpListener类的常用方法。方法方法说明说明AcceptSocket从端口处接收一个连接并赋予它Socket对象AcceptTcpClient从端口处接收一个连接并赋予它TcpClient对象Equals判断两个TcpListener对象是否相等GetHashCode用作特定类型的哈希函数GetType得到当前实例类型Pending确定是否有挂起的连接请求Start开始侦

5、听传入的连接请求Stop关闭侦听器ToString创建TcpListener对象的字符串表示TcpClient的构造函数有以下4种重载形式。(1)TcpClient( )。该构造函数创建一个默认的TcpClient对象,并自动分配本机(客户端)IP地址和端口号。利用此构造函数创建对象后,还必须调用Connect方法与服务器建立连接。例如:TcpClient tcpClient = new TcpClient();tcpClient.Connect(“”, 51888);(2)TcpClient(AddressFamily family)。构造函数创建的TcpClient对象也能自动分配本机(客

6、户端)IP地址和端口号,但是使用AddressFamily枚举指定使用哪种网络协议。创建该对象后,必须调用Connect方法与服务器建立连接。例如:TcpClient tcpClient = new TcpClient(AddressFamily.InterNetwork);tcpClient.Connect(“”, 51888);(3)TcpClient(IPEndPoint iep)。如果使用这种方式,必须调用Connect方法与服务器建立连接。例如:IPAddress address = Dns.GetHostAddresses (Dns.GetHostName();IPEndPoint

7、 iep = new IPEndPoint (address0, 51888);TcpClient tcpClient = new TcpClient(iep);tcpClient.Connect(“”, 51888);(4)TcpClient(string hostname, int port)。该构造函数会自动分配最合适的本地主机IP地址和端口号,并对DNS进行解析,然后与远程主机建立连接。例如:TcpClient tcpClient = new TcpClient(“”, 51888);它相当于:TcpClient tcpClient = new TcpClient();tcpClien

8、t Connect(“”, 51888);表3-2和表3-3分别列出了TcpClient类的常用属性和方法。属性属性含义含义Client获取或设置基础套接字LingerState获取或设置套接字保持连接的时间NoDelay获取或设置一个值,该值在发送或接收缓冲区未满时禁用延迟ReceiveBufferSize获取或设置Tcp接收缓冲区的大小ReceiveTimeout获取或设置套接字接收数据的超时时间SendBufferSize获取或设置Tcp发送缓冲区的大小SendTimeout获取或设置套接字发送数据的超时时间方法方法含义含义Close释放TcpClient实例,而不关闭基础连接Conne

9、ct用指定的主机名和端口号将客户端连接到TCP主机BeginConnect开始一个对远程主机连接的异步请求EndConnect异步接受传入的连接尝试GetStream获取能够发送和接收数据的NetworkStream对象3.4.1编写服务器端程序的一般步骤编写服务器端程序的一般步骤使用对套接字封装后的类,编写基于TCP的服务器端程序的一般步骤如下。(1)创建一个TcpListener对象,然后调用该对象的Start方法在指定的端口进行监听。典型代码如:/声明private IPAddress localAddress;/IP地址private const int port = 51888;/端

10、口private TcpListener tcpListener;/监听套接字/初始化IPAddress listenIp = Dns.GetHostAddresses();localAddress = listenIp0;/初始化IP为本地地址/创建TcpListener对象,开启监听tcpListener = new TcpListener(localAddress, port);tcpListener.Start();/监听开始(2)在单独的线程中,循环调用AcceptTcpClient方法接受客户端的连接请求,从该方法的返回结果中得到与该客户端对应的TcpClient对象,并利用该对象

11、的GetStream方法得到NetworkStream对象,然后再利用该对象得到其他使用更方便的对象如BinaryReader对象、BinaryWriter对象,为进一步与对方通信作准备。(3)每得到一个新的TcpClient对象,就创建一个与该客户对应的线程,在线程中与对应的客户进行通信。Thread threadReceive = new Thread(ReceiveMessage);threadReceive.Start();(4)根据传送信息的情况确定是否关闭与客户的连接。关闭连接的代码:if (br != null)br.Close();if (bw != null)bw.Close

12、();if (tcpClient != null)tcpClient.Close();toolStripStatusInfo.Text = 连接断开!;使用对套接字封装后的类,编写基于TCP的客户端程序的一般步骤如下。(1)利用TcpClient的构造函数创建一个TcpClient对象。private TcpClient tcpClient;tcpClient = new TcpClient();(2)使用Connect方法与服务器建立连接。tcpClient.Connect(remoteHost.HostName, int.Parse(tbxPort.Text);(3)利用TcpClient

13、对象的GetStream方法得到网络流,然后利用该网络流与服务器进行数据传输。if (tcpClient != null)statusStripInfo.Invoke(shwStatusInfoCallBack, 连接成功!);networkStream = tcpClient.GetStream();br = new BinaryReader(networkStream);bw = new BinaryWriter(networkStream);(4)创建一个线程监听指定的端口,循环接收并处理服务器发送过来的信息。Thread threadReceive = new Thread(Recei

14、veMessage);threadReceive.Start();(5)完成工作后,向服务器发送关闭信息,并关闭与服务器的连接。3.5.1 界面设计界面设计服务器与客户端程序设计简洁清晰风格的界面,如图3.5所示。程序界面上控件的属性描述见表3-4和表3-5。Name控件类型控件类型功能描述功能描述frmSyncTcpClientForm程序主窗体lstbxMsgViewListBox接收消息显示tbxSendCountTextBox设置消息发送数tbxReceiveCountTextBox设置消息接收数btnClearButton【清空】按钮btnReceiveButton【接收】按钮tbx

15、MsgTextBox编辑待发信息btnSendButton【发送】按钮tbxSrvIpTextBox填写服务器IPtbxPortTextBox填写服务端口btnConnectButton【连接】按钮btnDisconnectButton【断开】按钮toolStripStatusInfoToolStripStatusLabel状态栏文本标签toolStripProgressProcToolStripProgressBar状态栏进度条statusStripInfoStatusStrip状态栏Name控件类型控件类型功能描述功能描述frmSyncTcpServerForm程序主窗体lstbxMsgV

16、iewListBox接收消息显示tbxSendCountTextBox设置消息发送数tbxReceiveCountTextBox设置消息接收数btnClearButton【清空】按钮btnReceiveButton【接收】按钮tbxMsgTextBox编辑待发信息btnSendButton【发送】按钮btnStartButton【开始侦听】按钮btnStopButton【关闭侦听】按钮btnDisconnectButton【断开】按钮toolStripStatusInfoToolStripStatusLabel状态栏文本标签toolStripProgressProcToolStripProgr

17、essBar状态栏进度条statusStripInfoStatusStrip状态栏表表3-5同步服务器端界面控件描述同步服务器端界面控件描述首先声明4个委托:ShwMsgforViewCallBack、ShwStatusInfoCallBack、ShwProgressProcCallBack和ResetMsgTxtCallBack,然后将它们的实例分别绑定到定义好的4个函数(回调方法):ShwMsgforView、ShwStatusInfo、ShwProgressProc和ResetMsgTxt,通过回调方法间接地执行各自对应的界面操作:列表显示收到的消息、显示状态信息、显示进度和重置待发送的

18、消息文本。这是编写“线程安全”的程序时操作界面控件的普遍方法,整个程序的完整代码。与客户端程序一样,首先搭建好应用委托回调机制的框架,整个程序的完整代码。运行服务器和客户端程序,如图3.6所示。1. 服务器接受请求(服务器接受请求(tcpClient = tcpListener.AcceptTcpClient();)单击服务器【开始侦听】按钮,如图3.7所示。单击客户进程【连接】按钮,向服务器发起连接请求,产生的现象如图3.8所示。2. 接收数据(接收数据(string rcvMsgStr = br.ReadString();)单击服务器【接收】按钮,如图3.9所示。设置客户端发送消息数为5,

19、编辑消息内容后,单击“发送”按钮,运行效果如图3.10所示。单击客户端【发送】按钮,再发送5条消息,如图3.11所示。3. 发送数据(发送数据(bw.Write(state.ToString();)在服务器接收线程未开启的情况下,从客户端向服务器发消息,如图3.12所示。客户端发送完毕后,服务器并无反应。只有在单击服务器【接收】按钮后,才能看到收到的消息,如图3.13所示,发送消息后对方却是异步收到的!3.6.1 异步程序设计异步程序设计1. 基于基于IAsyncResult的异步设计模式的异步设计模式(1)基本原理。基于IAsyncResult的异步设计模式通过前缀分别为“Begin”和“E

20、nd”的两个方法实现开始和结束异步操作,每个Begin方法都必须有一个与其对应的End方法,如BeginAcceptTcpClient和EndAcceptTcpClient方法等。(2)AsyncCallback委托。AsyncCallback委托用于在异步操作完成时调用指定的回调方法。2. 异步异步TCP编程常用方法编程常用方法表3-6列出了TcpListener类、TcpClient类提供的部分异步操作方法。类类方法方法说明说明TcpListenerBeginAcceptTcpClient开始一个异步操作接受一个传入的连接尝试EndAcceptTcpClient异 步 接 受 传 入 的

21、连 接 尝 试 , 并 创 建 新 的TcpClient处理远程主机通信TcpClientBeginConnect开始一个对远程主机连接的异步请求EndConnect异步接受传入的连接尝试3. 异步方式调用同步方法异步方式调用同步方法(1)声明与要调用的方法具有相同签名的委托。下面的代码说明了如何声明一个与要调用的方法具有相同签名的委托:private BinaryWriter bw;private delegate void SendMessageDelegate(string sendMessage);private SendMessageDelegate sendMessageDeleg

22、ate;sendMessageDelegate = new SendMessageDelegate(AsyncSndMsg);private void AsyncSndMsg(string sendMessage)trybw.Write(sendMessage);bw.Flush();catch(2)通过轮询方式检查异步调用是否完成。声明和AsyncSndMsg方法具有相同签名的委托以后,公共语言运行时就会自动为该委托定义Beginlnvoke方法和Endlnvoke方法。然后就可以异步调用AsyncSndMsg方法了。调用Beginlnvoke方法后,该方法会立即返回IAsyncResult

23、类型的接口,从用户界面的服务线程中进行异步调用时,可以利用该接口的IsCompleted属性来通过轮询方式检查异步调用是否完成。在轮询过程中,Beginlnvoke方法在ThreadPool中创建的线程会继续执行异步方法。例如:private bool needExit;IAsyncResult result = sendMessageDelegate.BeginInvoke(sendMessage, null, null);while (result.IsCompleted = false)if (needExit)break;Thread.Sleep (50);(3)使用Endlnvoke

24、结束异步调用。Endlnvoke方法用于检索异步调用的结果,并结束异步调用。调用Beginlnvoke之后,随时可以调用该方法。如果异步调用尚未完成,则Endlnvoke会一直阻止调用线程,直到异步调用完成。例如,在退出轮询后,可以直接通过下面的代码结束异步调用:sendMessageDelegate.EndInvoke(result);给这个程序设计与3.5节程序一模一样的界面,只在窗体标题中注明这是异步程序,如图3.14所示。程序界面上控件的属性描述见表3-7和表3-8。Name控件类型控件类型功能描述功能描述frmAsyncTcpClientForm程序主窗体lstbxMsgViewLi

25、stBox接收消息显示tbxSendCountTextBox设置消息发送数tbxReceiveCountTextBox设置消息接收数btnClearButton【清空】按钮btnReceiveButton【接收】按钮tbxMsgTextBox编辑待发信息btnSendButton【发送】按钮tbxSrvIpTextBox填写服务器IPtbxPortTextBox填写服务端口btnConnectButton【连接】按钮btnDisconnectButton【断开】按钮toolStripStatusInfoToolStripStatusLabel状态栏文本标签toolStripProgressPr

26、ocToolStripProgressBar状态栏进度条statusStripInfoStatusStrip状态栏Name控件类型控件类型功能描述功能描述frmAsyncTcpServerForm程序主窗体lstbxMsgViewListBox接收消息显示tbxSendCountTextBox设置消息发送数tbxReceiveCountTextBox设置消息接收数btnClearButton【清空】按钮btnReceiveButton【接收】按钮tbxMsgTextBox编辑待发信息btnSendButton【发送】按钮btnStartButton【开始侦听】按钮btnStopButton【关

27、闭侦听】按钮btnDisconnectButton【断开】按钮toolStripStatusInfoToolStripStatusLabel状态栏文本标签toolStripProgressProcToolStripProgressBar状态栏进度条statusStripInfoStatusStrip状态栏表表3-8异步服务器端界面控件描述异步服务器端界面控件描述首先搭建好应用委托回调机制的通用框架,声明4个委托:ShwMsgforViewCallBack、ShwStatusInfoCallBack、ShwProgressProcCallBack和ResetMsgTxtCallBack,然后将它们的实例分别绑定到定义好的4个函数(回调方法):ShwMsgforView、ShwStatusInfo、ShwProgressProc和ResetMsgTxt。整个程序的完整代码。与客户端程序一样,首先搭建好应用委托回调机制的框架。由于这是异步服务器端,故如前一样,要专门定义两个异步操作方法AsyncRcvMsg和AsyncSndMsg,分别用来接收和发送信息,并且事先声明和实例化与它们具有相同签名的委托ReceiveMessageDelegate和SendMessageDel

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论