收藏 分享(赏)

C#TCP协议的程序设计.ppt

上传人:精品资料 文档编号:10798501 上传时间:2020-01-10 格式:PPT 页数:29 大小:1.22MB
下载 相关 举报
C#TCP协议的程序设计.ppt_第1页
第1页 / 共29页
C#TCP协议的程序设计.ppt_第2页
第2页 / 共29页
C#TCP协议的程序设计.ppt_第3页
第3页 / 共29页
C#TCP协议的程序设计.ppt_第4页
第4页 / 共29页
C#TCP协议的程序设计.ppt_第5页
第5页 / 共29页
点击查看更多>>
资源描述

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

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

3、ocket socketTimeout=new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);IPEndPoint myHost=new IPEndPoint(IPAddress.Any,8080);socketTimeout.SetSocket Option(SocketOptionLevel.Socket,SocketOptionName. ReceiveTimeout,3000);定时器,1/10/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方法将监视soc

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

6、操作。,1/10/2020,11,4.3 同步套接字编程技术,常规的网络聊天程序,相互发送文字信息。 服务器监听, 网络接收数据, 数据发送; 客户机发出连接请求,数据发送与接收。,1/10/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 Socket(Addre

7、ssFamily.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.Start()

8、;,1/10/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,sta

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

10、es(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.Encodin

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

12、nt(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();,1/10/2020,16,4.4 异步套接字编程技术,1/10/2020,17,(1) 客户机发出连接请求,客户端使用BeginConnect方法发出连接请求给服务器:Socket socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp); IPEndPoint iep=new IPEndPoint(IPAddress.Parse(“127.0.0.1“),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); ,1/10/2020,18,(2) 服务器接收连接请求,private Socket serverS

15、ocket,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);,1/10/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); ,1/10/2020,20,SendData方法,当套接字准备好发送的数据时,会自动调用SendData

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

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

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

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

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

23、ss localAddress=Dns.Resolve(Dns.GetHostName().AddressList0; IPEndPoint localEndPoint=new IPEndPoint(localAddress,8010); TcpListener tcpListener=new TcpListener(localEndPoint); /接着,开始侦听客户端的连接请求 tcpListener.Start(); /开始接收连接请求 TcpClient newClient=tcpListener.AcceptTcpClient();程序执行到AcceptTcpClient()时,会处

24、于阻塞状态,直到有客户端的连接请求到达。接收请求后会返回一个TcpClient对象,该对象将与此建立连接的客户端进行通信。,1/10/2020,26,4.6 网络游戏程序设计,服务器界面 客户机界面,1/10/2020,27,本章小结思考,同步套接字: 采用多路复用、多线程方法、异步选择函数; 异步套接字:能够很好地客户机/服务器的场合; TcpClient和TcpListener类的使用; ,1/10/2020,28,实验项目,1完成一个并发服务的TCP程序设计,要求如下: (1)界面上能够设定连接数量,比如连接数为100; (2)当一个连接释放后,程序能够自动分配给新的客户请求; (3)从多台客户机上分别连接服务器,测试并发服务效果; (4)连接完成后,使客户之间可以直接通信,不需要再经过服务器,服务器仅作管理用。 2修改网络游戏程序,达到以下功能: (1)能够设置每局的周期,比如1分钟; (2)能够更改比赛规则,比如3个相连时未输; (3)能够记录得分。 3网络游戏设计思考:请参考有关资料,尝试设计一个网络五子棋游戏。还可以考虑网上中国象棋、网络麻将等,并扩展到Web应用环境中。,1/10/2020,29,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报