资源预览内容
第1页 / 共35页
第2页 / 共35页
第3页 / 共35页
第4页 / 共35页
第5页 / 共35页
第6页 / 共35页
第7页 / 共35页
第8页 / 共35页
第9页 / 共35页
第10页 / 共35页
亲,该文档总共35页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
1第第10章章 TCP协议开发协议开发 10.1 相关相关概念概念 10.2 定义与获取主机信息定义与获取主机信息 10.3 同步套接字编程同步套接字编程 10.4 同步套接字开发举例同步套接字开发举例简单聊天程序简单聊天程序 10.5 使用使用TcpClient和和TcpListener简化简化TCP编程编程 10.6 异步套接字编程异步套接字编程 10.7 异步套接字开发举例异步套接字开发举例 210.1 基本概念基本概念基本概念(相关概念)基本概念(相关概念)同步同步 发送方将数据包发送到网络上以后,不等接收方响应,就接发送方将数据包发送到网络上以后,不等接收方响应,就接着发送下一个数据包。着发送下一个数据包。 异步异步 发送方将数据包发送到网络上以后,等接收方做出响应后,发送方将数据包发送到网络上以后,等接收方做出响应后,才接着发送下一个数据包。才接着发送下一个数据包。 3- 同步套接字同步套接字 在在通通过过Socket进进行行连连接接、接接收收、发发送送操操作作时时,客客户户机机或或服服务务器器会会暂暂停停当当前前工工作作,处处于于等等待待状状态态,即即一一直直等等到到有有数数据据时时才才继继续续执执行行下下面面的的语语句句。一一般般在在阻阻塞塞方方式式下下使使用用这这种种方方式式。可可见见,同同步步套套接接字字适适用用于于网网络络传传输输量量不不太太大大的的情情况况。当当网网络络传传输输量量很很大大时时,长长时时间间的的等等待待可可能能会会让让用用户无法忍受。户无法忍受。- 异步套接字异步套接字 在通过在通过Socket进行连接、接收、发送操作时,客户机或服进行连接、接收、发送操作时,客户机或服务器不会暂停当前工作,而是利用务器不会暂停当前工作,而是利用callback机制进行连接、机制进行连接、接收和发送处理。异步套接字适用于需要在网络上进行接收和发送处理。异步套接字适用于需要在网络上进行大量数据传输的应用程序,比如有几万客户同时传输的大量数据传输的应用程序,比如有几万客户同时传输的情况。情况。 410.2 定义与获取主机信息定义与获取主机信息定义主机对象定义主机对象IPEndPoint类类IPAddress类类获取主机信息获取主机信息Dns类中常用方法类中常用方法Dns.GetHostName() Dns.GetHostByName(string hostname) Dns.GetHostByAddress(address) Dns.Resolve() 51.定义主机对象定义主机对象 IPEndPointIPEndPoint 类类包包含含应应用用程程序序连连接接到到主主机机上上的的服服务务所所需需的的主主机机和和端端口口信信息息。通通过过组组合合服服务务的的主主机机 IP IP 地地址址和和端口号,端口号,IPEndPoint IPEndPoint 类形成到服务的连接点。类形成到服务的连接点。常用的方法原型:常用的方法原型:publicpublic IPEndPoint IPEndPoint( (IPAddress IPAddress address,address, int int port);port);说明:说明: addressaddress:IPIP地址地址 portport:端口号端口号功能:初始化功能:初始化IPEndPointIPEndPoint类的实例。类的实例。用法举例:用法举例: IPAddressmyServerIPIPAddressmyServerIP=new=new IPAddress IPAddress.Parse(“127.0.0.1”);.Parse(“127.0.0.1”); IPEndPoint myServer=new IPEndPoint(myServerIP,13); 62. 2. 主机解析主机解析程序实例程序实例Dns.Resolve()的使用的使用using System;using System.Net;public class TestFileStreamstatic void Main()Console.Write(输入主机名或者输入主机名或者IP地址:地址:);string str=Console.ReadLine();IPHostEntry host=Dns.Resolve(str);for(int i=0;i0)int recv=netStream.Read(message,start,dataleft);start+=recv;dataleft-=recv;his.richTextBoxAccept.Rtf=System.Text.Encoding.Unicode.GetString(message);catchthis.listBoxState.Items.Add(与客户断开与客户断开连接连接);break;18“停止监听停止监听”的的Click事件代码。事件代码。private void buttonStop_Click(object sender, System.EventArgs e)this.buttonStart.Enabled=true;trysocket.Shutdown(SocketShutdown.Both);socket.Close();if(clientSocket.Connected)clientSocket.Close();thread.Abort();catchMessageBox.Show(监听尚未开始,关闭监听尚未开始,关闭无效无效!);19添加添加“发送信息发送信息”的的Click事件代码。事件代码。 private void buttonSend_Click(object sender, System.EventArgs e)string str=this.richTextBoxSend.Rtf;int i=str.Length;if(i=0)return;else/因为因为str为为Unicode编码,每个字符占编码,每个字符占2字节,所以实际字节数字节,所以实际字节数应应*2i*=2;byte datasize=new byte4;datasize=System.BitConverter.GetBytes(i);byte sendbytes=System.Text.Encoding.Unicode.GetBytes(str);tryNetworkStream netStream=new NetworkStream(clientSocket);netStream.Write(datasize,0,4);netStream.Write(sendbytes,0,sendbytes.Length);netStream.Flush();this.richTextBoxSend.Rtf=;catchMessageBox.Show(无法发送无法发送!);20窗口关闭前触发的事件代码。窗口关闭前触发的事件代码。private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)trysocket.Shutdown(SocketShutdown.Both);socket.Close();if(clientSocket.Connected)clientSocket.Close();thread.Abort();catch21客户端编程客户端编程创建创建windows应用程序项目应用程序项目TestSyncClient,设计画面设计画面如图所示:如图所示: 控件属性参见表控件属性参见表10-2 22“请求连接请求连接”的的Click事件代码。事件代码。 private void buttonRequest_Click(object sender, System.EventArgs e)IPAddress ip=IPAddress.Parse(this.textBoxIP.Text);IPEndPoint server=new IPEndPoint(ip,Int32.Parse(this.textBoxPort.Text);socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);trysocket.Connect(server);catchMessageBox.Show(与服务器连接失败!与服务器连接失败!);return;this.buttonRequest.Enabled=false;this.listBoxState.Items.Add(与服务器连接成功与服务器连接成功);Thread thread=new Thread(new ThreadStart(AcceptMessage);thread.Start();23 private void AcceptMessage()while(true)tryNetworkStream netStream=new NetworkStream(socket);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,start,dataleft);start+=recv;dataleft-=recv;this.richTextBoxReceive.Rtf= System.Text.Encoding.Unicode.GetString(message);catch this.listBoxState.Items.Add(“服务器断开连接。服务器断开连接。”); break;24“关闭连接关闭连接”的的Click事件代码。事件代码。 private void buttonClose_Click(object sender, System.EventArgs e)trysocket.Shutdown(SocketShutdown.Both);socket.Close();this.listBoxState.Items.Add(与主机断开连接与主机断开连接);thread.Abort();catch MessageBox.Show(尚未与主机连接,断开无效尚未与主机连接,断开无效!);this.buttonRequest.Enabled=true; 25 关闭窗口前触发的事件代码。关闭窗口前触发的事件代码。 private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)trysocket.Shutdown(SocketShutdown.Both);socket.Close();catch26“发送信息发送信息”的的Click事件代码。事件代码。private void buttonSend_Click(object sender, System.EventArgs e)string str=this.richTextBoxSend.Rtf;int i=str.Length;if(i=0)return;elsei*=2;/因为因为str为为Unicode编码,每个字符占编码,每个字符占2字节,所字节,所以实际字节数应以实际字节数应*2byte datasize=new byte4;datasize=System.BitConverter.GetBytes(i); byte sendbytes=System.Text.Encoding.Unicode.GetBytes(str);tryNetworkStream netStream=new NetworkStream(socket);netStream.Write(datasize,0,4);netStream.Write(sendbytes,0,sendbytes.Length);netStream.Flush();this.richTextBoxSend.Text=;catchMessageBox.Show(无法发送无法发送!);2710.5 使用使用TcpClient和和TcpListener类简化类简化TCP编程编程TcpClient类类 TcpClient() TcpClient(IPEndPoint iep) TcpClient(string host,int port) 常用属性和方法(表常用属性和方法(表103、表、表104)TcpListener类类 TcpListener(int port) TcpListener(IPAddress address,int port) TcpListener(IPEndPoint iep) 常用方法(表常用方法(表105)2810.6 异步套接字编程异步套接字编程 异步套接字及其常用方法(表异步套接字及其常用方法(表106)BeginAccept()方法和方法和EndAccept()方法方法异步异步Socket中使用中使用BeginAccept方法开始接收新的连接请求,其方法开始接收新的连接请求,其方法原型为:方法原型为:public IAsyncResult BeginAccept(AsyncCallback callback,Object state) 其中:参数其中:参数1为为AsyncCallback类型的委托,委托提供的方法类型的委托,委托提供的方法用于接收连接并且调用用于接收连接并且调用EndAccept();参数参数2为为Object类型,用于类型,用于将状态信息传递给委托提供的方法。将状态信息传递给委托提供的方法。Socket socket=new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);IPEndPoint iep=new IPEndPoint(IPAddress.Any,6788);socket.Bind(iep); socket.Listen(10);socket.BeginAccept(new AsyncCallback(ClientConnected),socket); 29BeginAccept()方法和方法和EndAccept()方法方法EndAccept()的格式为:的格式为:Socket EndAccept(IAsyncResult ar) IAsyncResult对象将对象将IAsyncResult值从关联的值从关联的BeginAccept()方法传递到方法传递到EndAccept()方法。方法。 ClientConnected ()方法的使用形式为:方法的使用形式为:private void ClientConnected( IAsyncResult ar)Socket server=(Socket)ar.AsyncState;Socket client=server.EndAccept(ar); 参数中的参数中的IAsyncResult类型表示异步操作的状态,类型表示异步操作的状态,ar是是socket.BeginAccept()得到的返回值。得到的返回值。30BeginAccept()方法和方法和EndAccept()方法方法在在ClientConnected()方法中,首先根据方法中,首先根据BeginAccept()方法传方法传递的原始递的原始Socket对象得到一个新的对象得到一个新的Socket对象,然后根据这对象,然后根据这个对象创建客户端个对象创建客户端Socket对象,一旦创建了客户端对象,一旦创建了客户端Socket对对象,就可以使用同步或者异步的方法与客户端进行通信。象,就可以使用同步或者异步的方法与客户端进行通信。 使用使用BeginAccept方法时,类型为方法时,类型为Object的状态参数可以用的状态参数可以用一个类来实现,例如:一个类来实现,例如:public class StateObjectpublic Socket workSocket=null; public const int bufferSize=1024;public byte buffer=new bytebufferSize;public StringBuilder sb=new StringBuilder(); 然后通过创建该类的实例提供连接请求的状态。然后通过创建该类的实例提供连接请求的状态。 31 BeginConnect()方法和方法和EndConnect()方法方法 异步套接字编程中,客户端使用异步套接字编程中,客户端使用BeginConnect()方法连接到远程方法连接到远程主机,其格式为:主机,其格式为:IAsyncResult BeginConnect(EndPoint ep, AsyncCallBack callback, Object state) 其中第一个参数是远程主机的其中第一个参数是远程主机的EndPoint对象,第二个参数用于对象,第二个参数用于和远程主机连接成功后执行委托调用的方法,最后一个参数是状和远程主机连接成功后执行委托调用的方法,最后一个参数是状态对象,用于传递必要的数据态对象,用于传递必要的数据 。32BeginConnect()方法和方法和EndConnect()方法方法 程序执行到程序执行到BeginConnect()方法时,不会停下来等待完成连接,方法时,不会停下来等待完成连接,而是继续往下执行,同时而是继续往下执行,同时BeginConnect()方法也继续运行,一旦方法也继续运行,一旦BeginConnect()连接到远程主机,连接到远程主机,AsyncCallback委托就会自动调用委托就会自动调用Connected()方法。方法。 根据这个原理,我们就可以在根据这个原理,我们就可以在Connected()方法中获得连接的方法中获得连接的Socket实例,并调用实例,并调用EndConnect()方法完成连接请求。方法完成连接请求。 EndConnect()方法的格式为:方法的格式为:public void EndConnect(IasyncResult ar) 33 异步发送和接收数据异步发送和接收数据 服务器和远程客户端建立连接后,就可以发送和服务器和远程客户端建立连接后,就可以发送和接收数据了。在异步套接字中,使用接收数据了。在异步套接字中,使用BeginSend()方法发送数据,使用方法发送数据,使用BeginReceive()方法接收数据方法接收数据 。BeginSend()方法的使用格式为:方法的使用格式为:IasyncResule BeginSend(byte buffer,int offset, int size, SocketFlags sockflag, AsyncCallback callback, object state)EndSend()方法用于完成数据的发送,并返回成功方法用于完成数据的发送,并返回成功发送的字节数。该方法的格式为:发送的字节数。该方法的格式为:public int EndSend(IasyncResult ar)3410.6 异步套接字编程异步套接字编程异步发送和接收数据异步发送和接收数据接收数据的方法和发送数据相似,具体使用方法可参接收数据的方法和发送数据相似,具体使用方法可参看下节的例子看下节的例子 3510.7 异步套接字开发举例异步套接字开发举例本节自学本节自学详见教材详见教材
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号