P3 基于TCP协议的程序设计

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

2/10/20201计算机网络编程技术第3章基于TCP协议的程序设计2/10/20202本章的主要内容回顾TCP协议的基本特点了解阻塞模式和非阻塞模式同步套接字编程技术异步套接字编程技术2/10/202033.1TCP协议介绍(1)TCP协议提供服务的特点:①面向连接的传输;②端到端的通信;③高可靠性,确保传输数据的正确性,不出现丢失或乱序;④全双工方式传输;⑤采用字节流方式,即以字节为单位传输字节序列;⑥紧急数据传送功能。2/10/20204(2)TCP数据包格式TCP头部数据源端口号目的端口号序号头部长度校验和(16位)窗口大小选项及填充确认号保留URGACKPSHRSTSYNFIN紧急指针0151631注意标志位的作用注意选项的作用,如何使用选项部分?2/10/20205(3)TCP协议的通信特点3次握手;4次挥手;回顾拥塞控制2/10/20206(4)TCP的熟知端口端口号服务进程描述20FTP文件传输协议(数据连接)21FTP文件传输协议(控制连接)23Telnet虚拟终端网络25SMPT简单邮件传输协议53DNS域名服务器80HTTP超文本传输协议111RPC远程过程调用2/10/202073.2阻塞模式/非阻塞模式同步异步阻塞模式:读、写、连接、接收非阻塞模式2/10/202083.2.1阻塞模式的效率提升方法(1)超时控制方法套接字选项设置:SetSockOption(),GetSockOption()应用示例:SocketsocketTimeout=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);IPEndPointmyHost=newIPEndPoint(IPAddress.Any,8080);socketTimeout.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,3000);定时器2/10/20209(2)套接字多路复用方法C#使用Socket类提供的Select方法。应用示例:ArrayListsocketList=newArrayList(5);socketList.Add(sock1);socketList.Add(sock2);Socket.Select(socketList,null,null,1000);Byte[]buffer=newtype[1024];for(inti=0;isocketList.Length-1;i++){socketList[i].Receive(buffer);Console.WriteLine(System.Text.Encoding.ASCII.GetString(buffer);}这样,Select方法将监视sock1和sock2两个套接字上接收的数据。2/10/202010(3)调用异步选择函数AsyncSelect()在VC++编程环境中使用;对于winsock2.0,采用:WSAAsyncSelect()函数2/10/2020113.2.2非阻塞模式的应用(1)非阻塞套接字Socketsock=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);sock.Blocking=false;(2)异步套接字采用异步回调AsyncCallback,委托为应用程序提供完成异步操作。2/10/2020123.3同步套接字编程技术常规的网络聊天程序,相互发送文字信息。服务器监听,网络接收数据,数据发送;客户机发出连接请求,数据发送与接收。2/10/202013服务器“开始监听”的主要代码this.btnStartListen.Enabled=false;IPAddressip=IPAddress.Parse(this.textBoxIP.Text);IPEndPointserver=newIPEndPoint(ip,Int32.Parse(this.textBoxPort.Text));socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);socket.Bind(server);//监听客户端连接socket.Listen(10);newSocket=socket.Accept();//显示客户IP和端口号this.lbState.Items.Add(与客户+newSocket.RemoteEndPoint.ToString()+建立连接);//创建一个线程接收客户信息thread=newThread(newThreadStart(AcceptMessage));thread.Start();2/10/202014服务器“数据接收”的主要代码NetworkStreamnetStream=newNetworkStream(newSocket);byte[]datasize=newbyte[4];netStream.Read(datasize,0,4);intsize=System.BitConverter.ToInt32(datasize,0);Byte[]message=newbyte[size];intdataleft=size;intstart=0;while(dataleft0){intrecv=netStream.Read(message,start,dataleft);start+=recv;dataleft-=recv;}接收数据的方法有2种:使用Socket类的Receive方法使用NetworkStream类的Read方法。Read方法的返回值是一个整数,表明实际从TCP缓冲区中读取的字节数,可能少于远端发来的数据量。2/10/202015服务器“数据发送”的主要代码发送数据也有2种方法:使用Socket类的Send方法,应用示例:byte[]bytes=newbyte[2048];stringmessage=测试数据发送;bytes=System.Text.Encoding.Unicode.GetBytes(message);newSocket.Send(bytes,bytes.Length,SocketFlags.None);使用NetworkStream类的Write方法,能够保证将用户数据全部发送到TCP缓冲区中,自动完成。不需要用户管理,简化了编程工作。stringstr=this.rtbSend.Rtf;inti=str.Length;byte[]datasize=newbyte[4];datasize=System.BitConverter.GetBytes(i);//将位整数值转换为字节数组byte[]sendbytes=System.Text.Encoding.Unicode.GetBytes(str);NetworkStreamnetStream=newNetworkStream(newSocket);netStream.Write(datasize,0,4);netStream.Write(sendbytes,0,sendbytes.Length);netStream.Flush();this.rtbSend.Rtf=;2/10/202016客户机“连接请求”的主要代码IPAddressip=IPAddress.Parse(this.tbIP.Text);IPEndPointserver=newIPEndPoint(ip,Int32.Parse(this.tbPort.Text));socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);try{socket.Connect(server);}catch{MessageBox.Show(与服务器连接失败!);return;}this.btnRequest.Enabled=false;this.lbState.Items.Add(与服务器连接成功);Threadthread=newThread(newThreadStart(AcceptMessage));thread.Start();2/10/2020173.4异步套接字编程技术配套的方法功能BeginAccept(),EndAccept()服务器接收一个连接请求BeginConnect(),EndConnect()客户端连接到服务器BeginReceive(),EndReceive()接收数据BeginReceiveFrom(),EndReceiveFrom()从指定的主机上接收数据BeginSend(),EndSend()发送数据BeginSendTo(),EndSendTo()将数据发送到指定的主机2/10/202018(1)客户机发出连接请求客户端使用BeginConnect方法发出连接请求给服务器:Socketsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);IPEndPointiep=newIPEndPoint(IPAddress.Parse(127.0.0.1),8000);socket.BeginConnect(iep,newAsyncCallback(ConnectServer),socket);privatevoidConnectServer(IAsyncResultar){clientSocket=(Socket)ar.AsyncState;clientSocket.EndConnect(ar);clientSocket.BeginReceive(data,0,dataSize,SocketFlags.None,newAsyncCallback(ReceiveData),clientSocket);}2/10/202019(2)服务器接收连接请求privateSocketserverSocket,newSocket;IPHostEntrymyHost=newIPHostEntry();myHost=Dns.GetHostByName(NetHost);//主机名称NetHostIPAddressmyIP=IPAddress.Parse(myHost.AddressList[0].ToString());//选取第1个地址IPEndPointiep=newIPEndPoint(myIP,8000);serverSocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);serverSocket.Bind(iep);serverSocket.Listen(5);//监听队列为5//开始异步接收连接请求serverSocket.BeginAccept(newAsyncCallback(AcceptConnection),serverSocket);2/10/202020(3)服务器发送和接收数据一旦服务器接收到一个客户机连接请求,AsyncCallback委托将自动调用AcceptConnection方法。privatevoidAcceptConnection(IAsyncResultar){SocketmyServer=(Socket)ar.AsyncState;//异步接收传入的连接,并创建新的Socket来处理远程主机通信newSocket=myServer.EndAccept(ar);byte[]message=System.Text.En

1 / 29
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功