C#TCP协议的程序设计_第1页
C#TCP协议的程序设计_第2页
C#TCP协议的程序设计_第3页
C#TCP协议的程序设计_第4页
C#TCP协议的程序设计_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

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

文档简介

1、C#网络通信程序设计,第3章 基于TCP协议的程序设计,本章的主要内容,学习内容: (1)了解TCP协议的特点与数据包格式; (2)理解阻塞模式和非阻塞模式的特点及其应用; (3)掌握同步套接字编程和异步套接字编程方法; (4)掌握TcpListener和TcpClient的综合应用方法。 学习目标: (1)掌握基于TCP协议的同步/异步套接字编程方法; (2)学会基于C/S结构的网络聊天程序设计与实现能力,8/12/2020,2,4.1 TCP协议介绍,(1) TCP协议提供服务的特点: 面向连接的传输; 端到端的通信; 高可靠性,确保传输数据的正确性,不出现丢失或乱序; 全双工方式传输;

2、采用字节流方式,即以字节为单位传输字节序列; 紧急数据传送功能。,8/12/2020,3,(2) TCP数据包格式,注意标志位的作用 注意选项的作用, 如何使用选项部分?,8/12/2020,4,(3) TCP协议的通信特点,3次握手; 4次挥手; 回顾拥塞控制,8/12/2020,5,(4) TCP的常见端口,8/12/2020,6,4.2 阻塞模式/非阻塞模式,同步 异步 阻塞模式: 读、写、连接、接收 非阻塞模式,8/12/2020,7,4.2.1 阻塞模式的效率提升方法,(1) 超时控制方法 套接字选项设置:SetSockOption(), GetSockOption() 应用示例:

3、Socket socketTimeout=new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPoint myHost=new IPEndPoint(IPAddress.Any,8080); socketTimeout.SetSocket Option(SocketOptionLevel.Socket,SocketOptionName. ReceiveTimeout,3000); 定时器,8/12/2020,8,(2) 套接字多路复用方法,C#使用Socket类提供的Select方法。

4、应用示例: ArrayList socketList=new ArrayList(5); socketList.Add(sock1); socketList.Add(sock2); Socket.Select(socketList,null,null,1000); Byte buffer=new type1024; for(int i=0;isocketList.Length-1;i+) socketListi.Receive(buffer); Console.WriteLine(System.Text.Encoding.ASCII.GetString(buffer); 这样,Select方法

5、将监视sock1和sock2两个套接字上接收的数据。,8/12/2020,9,(3) 调用异步选择函数AsyncSelect(),在VC+编程环境中使用; 对于winsock 2.0,采用: WSAAsyncSelect()函数,8/12/2020,10,4.2.2 非阻塞模式的应用,(1) 非阻塞套接字 Socket sock=new Socket(AddressFamily.InterNetwork, SocketType.Stream,Protocol Type.Tcp); sock. Blocking=false; (2) 异步套接字 采用异步回调AsyncCallback,委托为应用

6、程序提供完成异步操作。,8/12/2020,11,4.3 同步套接字编程技术,常规的网络聊天程序,相互发送文字信息。 服务器监听, 网络接收数据, 数据发送; 客户机发出连接请求,数据发送与接收。,8/12/2020,12,服务器“开始监听”的主要代码,this.btnStartListen.Enabled=false; IPAddress ip=IPAddress.Parse(this.textBoxIP.Text); IPEndPoint server=new IPEndPoint(ip,Int32.Parse(this.textBoxPort.Text); socket=new Sock

7、et(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); socket.Bind(server); /监听客户端连接 socket.Listen(10); newSocket=socket.Accept(); /显示客户IP和端口号 this.lbState.Items.Add(与客户+newSocket.RemoteEndPoint.ToString()+ 建立连接); /创建一个线程接收客户信息 thread=new Thread(new ThreadStart(AcceptMessage); thread.Sta

8、rt();,8/12/2020,13,服务器“数据接收”的主要代码,NetworkStream netStream=new NetworkStream(newSocket); byte datasize=new byte4; netStream.Read(datasize,0,4); int size=System.BitConverter.ToInt32(datasize,0); Byte message=new bytesize; int dataleft=size; int start=0; while(dataleft0) int recv=netStream.Read(message

9、,start,dataleft); start+=recv; dataleft-=recv; ,接收数据的方法有2种: 使用Socket类的Receive方法 使用NetworkStream类的Read方法。Read方法的返回值是一个整数,表明实际从TCP缓冲区中读取的字节数,可能少于远端发来的数据量。,8/12/2020,14,服务器“数据发送”的主要代码,发送数据也有2种方法: 使用Socket类的Send方法,应用示例: byte bytes=new byte2048; string message=测试数据发送; bytes=System.Text.Encoding.Unicode.G

10、etBytes(message); newSocket.Send(bytes, bytes.Length, SocketFlags.None); 使用NetworkStream类的Write方法 ,能够保证将用户数据全部发送到TCP缓冲区中,自动完成。不需要用户管理,简化了编程工作。 string str=this.rtbSend.Rtf; int i=str.Length; byte datasize=new byte4; datasize=System.BitConverter.GetBytes(i); /将位整数值转换为字节数组 byte sendbytes=System.Text.En

11、coding.Unicode.GetBytes(str); NetworkStream netStream=new NetworkStream(newSocket); netStream.Write(datasize,0,4); netStream.Write(sendbytes,0,sendbytes.Length); netStream.Flush(); this.rtbSend.Rtf=;,8/12/2020,15,客户机“连接请求”的主要代码,IPAddress ip=IPAddress.Parse(this.tbIP.Text); IPEndPoint server=new IPEn

12、dPoint(ip, Int32.Parse(this.tbPort.Text); socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp); try socket.Connect(server); catch MessageBox.Show(与服务器连接失败!); return; this.btnRequest.Enabled=false; this.lbState.Items.Add(与服务器连接成功); Thread thread=new Thread(new ThreadStart

13、(AcceptMessage); thread.Start();,8/12/2020,16,4.4 异步套接字编程技术,8/12/2020,17,(1) 客户机发出连接请求,客户端使用BeginConnect方法发出连接请求给服务器: Socket socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep=new IPEndPoint(IPAddress.Parse(),8000); socket.BeginConnect(iep,new

14、AsyncCallback(ConnectServer),socket); private void ConnectServer(IAsyncResult ar) clientSocket=(Socket)ar.AsyncState; clientSocket.EndConnect(ar); clientSocket.BeginReceive(data,0,dataSize,SocketFlags.None, new AsyncCallback(ReceiveData),clientSocket); ,8/12/2020,18,(2) 服务器接收连接请求,private Socket serv

15、erSocket,newSocket; IPHostEntry myHost=new IPHostEntry(); myHost=Dns.GetHostByName(NetHost);/主机名称NetHost IPAddress myIP=IPAddress.Parse(myHost.AddressList0.ToString();/选取第1个地址 IPEndPoint iep=new IPEndPoint(myIP,8000); serverSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,Protocol Type

16、.Tcp); serverSocket.Bind(iep); serverSocket.Listen(5);/监听队列为5 /开始异步接收连接请求 serverSocket.BeginAccept(new AsyncCallback(AcceptConnection),serverSocket);,8/12/2020,19,(3) 服务器发送和接收数据,一旦服务器接收到一个客户机连接请求,AsyncCallback委托将自动调用AcceptConnection方法。 private void AcceptConnection(IAsyncResult ar) Socket myServer=(

17、Socket)ar.AsyncState; /异步接收传入的连接,并创建新的Socket来处理远程主机通信 newSocket=myServer.EndAccept(ar); byte message=System.Text.Encoding.Unicode.GetBytes(客户你好!); newSocket.BeginSend(message,0,message.Length,SocketFlags.None,new AsyncCallback(SendData),newSocket); ,8/12/2020,20,SendData方法,当套接字准备好发送的数据时,会自动调用SendDat

18、a方法。EndSend方法用于完成数据发送,并返回成功发送的字节数。该段程序示例如下: private void SendData(IAsyncResult ar) Socket client=(Socket)ar.AsyncState; try newSocket.EndSend(ar); client.BeginReceive(data,0,dataSize,SocketFlags.None, new AsyncCallback (ReceiveData),client); 异步接收数据 catch client.Close(); serverSocket.BeginAccept(new

19、AsyncCallback(AcceptConnection),server Socket); /开始异步接收新的连接请求 ,8/12/2020,21,课堂思考,如何图形化描述以上异步套接字各种状态之间的状态变化?如状态转换图?,8/12/2020,22,4.5 基于TcpClient类和TcpListener类的编程,TcpClient类和TcpListener类是构建于Socket之上,提供了更高抽象级别的TCP服务,便于程序员快速编写网络程序。 TcpClient类用于客户机,TcpListener类用于服务器。,8/12/2020,23,(1) TcpClient类的使用方法,第12

20、阶段: 方法1: 先创建,后连接: /创建TcpClient实例 TcpClient client=new TcpClient(); /向服务器发出连接请求 client.Connect(,8000); 方法2 : 直接指定和连接服务器: TcpClient client=new TcpClient(,8000); 方法3: 指定IPEndPoint的方式: IPEndPoint localEndPoint=new IPEndPoint(IPAddress.Parse(8),8010); TcpClient

21、client=new TcpClient(localEndPoint); client.Connect(,8000);,4个阶段: 创建实例、连接服务器、收发数据和关闭连接。,8/12/2020,24,(1) TcpClient类的使用方法,/第三阶段: 数据接收 netStream=client.GetStream(); sr=new StreamReader(netStream,System.Text.Encoding.Unicode); str=sr.ReadLine(); Console.WriteLine(str); /第三阶段:数据发送 ws=cli

22、ent.GetStream(); ws.Write(data,0,data.Length); /或者 sw=new StreamWriter(ws,System.Text.Encoding.Unicode); sw.WriteLine(str); sw.Flush(); . /第4阶段:连接关闭 client.Close();,4个阶段: 创建实例、连接服务器、收发数据和关闭。,8/12/2020,25,(2) TcpListener类的使用方法,TcpListener类用于监听和接收传入的连接请求,包括创建实例、监听连接、接收连接请求、收发数据和停止服务共5个阶段。 典型用法如下: IPAddress localAddress=Dns.Resolve(Dns.GetHostName().AddressList0; IPEndPoint loc

温馨提示

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

评论

0/150

提交评论