版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第8章 MyQQ的设计8.1 项目的创建8.2 数据包的设计8.3 主界面的设计8.4 聊天窗口的设计8.5 读者完成部分第1页,共76页。知识点链接L8.1 项目的创建L8.3 主界面的设计L8.5 读者完成部分第2页,共76页。1. MyQQ的介绍当双击所要聊天对象时弹出聊天窗口,聊天窗口如图8.2所示,用于发送信息和显示聊天信息。 图8.1 MyQQ主界面 图8.2 聊天窗口第3页,共76页。2所要掌握的主要知识点(1)网络通信知识点,Socket、TcpListener、TcpClient和UdpClient类。(2)线程知识点,Thread类。(3)熟悉ListView控件、Noti
2、fyIcon组件的使用。第4页,共76页。8.1 项目的创建MyQQ应用程序主要讲述网络通信和多线程,包括主界面窗体和聊天窗口窗体这两个窗体,主界面主要显示在线的人物以及选择聊天对象,聊天窗口用于发送聊天信息和接受聊天信息。此项目中同时还包括封装数据包的类DataPacket。项目的创建步骤:1创建项目运行VS2008,执行【文件】【新建】【项目】命令,在弹出的“新建项目”对话框中选中“Windows窗体应用程序”模板,选择项目存放位置并输入项目名称为“MyQQ”,单击“确定”按钮完成项目的创建。2添加窗体打开“解决方案资源管理器”窗口,右击项目名“MyQQ”,依次执行快捷菜单中的“添加”“新
3、建项”命令,在弹出的“添加新项”对话框中选中“Windows窗体”模板,使用默认名称“Form1”,单击“添加”按钮完成窗体的添加。按照同样的方法再添加一个窗体,使用默认命名。其中“Form1”为主界面窗体,“Form2”为聊天窗口窗体。第5页,共76页。8.1 项目的创建3添加类DataPacket在“解决方案资源管理器”窗口中,右击项目名“MyQQ”,依次执行快捷菜单中的“添加”“新建项”命令,在弹出的“添加新项”对话框中选中“类”模板,命名为“DataPacket.cs”并单击“添加”按钮。到此完成了整个项目的创建。第6页,共76页。8.2 数据包的设计数据包格式包括“命令号”、“发送端
4、IP”、“用户名长度”、“用户名”、“接受端IP”和“内容”6个部分。命令号是说明此数据包用于所要执行的任务,发送端IP是指发送信息端的IP地址,用户名为发送端的用户名,用户名的字节数是指发送端的用户名的字节数,接受端IP是指所要发送到对方的IP地址,内容是指数据包所附带的信息。数据包的结构如图8.3所示。图8.3 数据包结构第7页,共76页。8.2 数据包的设计设计步骤:1. 添加命名空间打开类DataPacket,因为此类中涉及网络,所以要添加如下命名空间:using System.Net;2. 添加其他代码代码如下。第8页,共76页。8.3 主界面的设计主界面窗体运行后如图8.1所示,通
5、过ListView控件和ImageList显示在线的人物以及选择聊天对象,通过StatusStrip控件显示在线人数以及包括“上线”和“下线”功能。设计步骤:1. 添加控件和组件在解决方案资源管理器中打开“Form1.cs”。将Form1窗体调整到适当大小,从工具箱中拖放1个“NotifyIcon”组件、1个“ListView”和1个“ImageList”控件到此窗体中。参考图8.1所示摆放控件。第9页,共76页。8.3 主界面的设计2. 设置窗体和控件组件的属性Form1的Text属性值设置为“MyQQ”,Icon设置为已经准备好的图标,MaximizeBox设置为“False”。(1)no
6、tifyIcon1的属性设置。Icon选择已经准备好的图标,Text设置为“MyQQ”。(2)imageList1的属性设置。在其属性窗口中打开“ ”按钮图标,弹出“图像集合编辑器”窗口,分别添加一些用于显示聊天对象的图标,如图8.4所示。图8.4 图像集合编辑器第10页,共76页。8.3 主界面的设计(3)listView1的属性设置。打开listView1属性窗口,FullRowSelect和View属性值分别设置为“True”和“Title”,MultiSelect设置为“False”,StateImageList属性选择为“imageList1”,Columns集合中分别添加3个“co
7、lumnHeader”成员。(4)statusStrip1的设置。分别添加一个“toolStripStatusLabel”和一个“toolStripDropDownButton”。toolStripStatusLabel1的Text属性设置为“在线人数 人”,选中toolStripDropDownButton1Text,分别添加“上线”和“下线”选项,如图8.5所示,Image选择准备好的图标。图8.5 添加上下线第11页,共76页。8.3 主界面的设计3. 添加事件及代码主窗口窗体包含有“窗体加载”、“上线”、“下线”、“选择聊天对象”和“调整大小”事件。(1)添加命名空间。因为涉及线程和网
8、络的操作,所以添加命名空间如下:using System.Threading;using System.Net;using System.Net.Sockets;(2)添加字段。所添加的字段如下所示:private UdpClient UdpListen = new UdpClient(8000);private IPAddress myIP = Dns.GetHostEntry(Dns.GetHostName().AddressList0;/本机器IP地址private string myName = Environment.UserName; /本机器用户名/*标识网络地址,初始化广播端口
9、号*/private IPEndPoint EndPoint = new IPEndPoint(IPAddress.Parse(55), 8000);private static bool MyState = false;/是否为在线状态第12页,共76页。8.3 主界面的设计(3)主界面中添加上线人的成员方法。通过数据包参数将此上线的人的用户名、IP地址以及图像显示在主界面中,并更新在线人数。代码如下:private void AddPerson(DataPacket dp) /添加聊天的人 ListViewItem lviUserName = new ListViewItem(); Lis
10、tViewItem.ListViewSubItem lvsiComputerName = new ListViewItem.ListViewSubItem(); ListViewItem.ListViewSubItem lvsiIP = new ListViewItem.ListViewSubItem(); lvsiComputerName.Text = dp.ComputerName; lvsiIP.Text = dp.FromIP.ToString(); int imagecount = listView1.Items.Count % imageList1.Images.Count; /选
11、择图像 lviUserName.StateImageIndex = imagecount; lviUserName.SubItems.Add(lvsiComputerName); lviUserName.SubItems.Add(lvsiIP); listView1.Items.Add(lviUserName); toolStripStatusLabel1.Text = 在线人数: + listView1.Items.Count + 人;/显示聊天人数第13页,共76页。8.3 主界面的设计(4)监听指定端口的广播地址UDP包的成员方法的代码。当接受到数据包时,分析其包的命令,并执行相应的代码
12、。代码如下所示。(5)添加“窗体加载”事件及其代码。当窗体加载时就开启监听线程,切换到Form1的设计视图,双击窗体,添加代码,代码如下所示:private void Form1_Load(object sender, EventArgs e) /*开启监听线程*/ Thread myThread = new Thread(new ThreadStart(this.ListenPort); myThread.IsBackground = true; myThread.Start(); Control.CheckForIllegalCrossThreadCalls = false;/忽略跨线程错
13、误,这时会抛出异常第14页,共76页。8.3 主界面的设计(6)添加上下线事件及其代码。当单击“上线”和“下线”时分别发送“上线”和“下线”数据包。切换到设计视图并分别双击“上线”和“下线”,添加事件代码,代码如下。第15页,共76页。8.3 主界面的设计(7)添加选中聊天对象事件及其代码。当双击聊天对象时弹出聊天窗口并发生聊天请求数据包。在listView1的事件窗口中双击DoubleClick,添加其事件代码,代码如下:private void listView1_DoubleClick(object sender, EventArgs e)/聊天 string strChatIP = l
14、istView1.SelectedItems0.SubItems2.Text; IPAddress IPAddChatIP = IPAddress.Parse(strChatIP); Form2 form2 = new Form2(myIP, myName, IPAddChatIP); form2.Show(); /*发送聊天请求数据包*/ DataPacket comeDataPacket = new DataPacket(); comeDataPacket.CommandNo = 1; comeDataPacket.FromIP = myIP; comeDataPacket.NameLen
15、gth = myName.Length; comeDataPacket.ComputerName = myName; comeDataPacket.ToIP = IPAddChatIP; comeDataPacket.Content = 聊天请求; byte sendb = comeDataPacket.PacketToBytes(); UdpListen.Send(sendb, sendb.Length, EndPoint);/发送信息第16页,共76页。8.3 主界面的设计(8)添加关闭窗口事件及其代码。当关闭窗口退出程序时发送下线数据包。打开Form1的事件窗口,双击“FormClose
16、d”,添加其事件代码,代码如下:private void Form1_FormClosed(object sender, FormClosedEventArgs e)/关闭窗口 下线ToolStripMenuItem_Click(null, null);/下线(9)添加调整大小事件。当最小化主界面时,最小化到任务栏状态通知区域中。打开Form1的事件窗口,双击“Resize”,添加其事件代码,代码如下:private void Form1_Resize(object sender, EventArgs e) if (this.WindowState = FormWindowState.Mini
17、mized) this.Visible = false; /隐藏窗体 this.notifyIcon1.Visible = true; /在托盘中显示图标 第17页,共76页。8.3 主界面的设计(10)添加notifyIcon1的双击事件。打开notifyIcon1的事件窗口,双击“DoubleClick”,添加其事件代码,代码如下:private void notifyIcon1_DoubleClick(object sender, EventArgs e) this.Visible = true;/显示主窗口 this.WindowState = FormWindowState.Norm
18、al; this.notifyIcon1.Visible = false; 第18页,共76页。8.3 主界面的设计4. 运行程序按【Ctrl+F5】组合键运行程序。选择上线选项,则自己的图标、用户名和IP地址显示在主界面中。当最小化MyQQ时,进程图标显示在任务栏状态通知区域中。如图8.6所示。图8.6 MyQQ进程图标第19页,共76页。8.4 聊天窗口的设计聊天窗口用于发送聊天信息给聊天对象并接受聊天对象的信息。在这里为了突出知识点和教学方便,使用传输控制协议 (TCP)只实现发送信息给自己并接受信息。运行的界面如图8.2所示。设计步骤:1. 添加控件在解决方案资源管理器中打开“Form
19、2.cs”。将Form2窗体调整到适当大小,从工具箱中拖放1个“toolStrip1”、2个“TextBox”和2个“Button”控件到此窗体中。参考图8.2所示摆放控件。2. 窗体和控件属性设置打开Form2的属性窗口,Text属性设置为“MyQQ”,MaximizeBox、MinimizeBox和ShowIcon的属性值都设置为“False”。StartPosition属性值设置为“CenterScreen”。button1和button2的Text属性值设置为“发送”和“关闭”。toolStrip1学生可以自己设计。第20页,共76页。8.4 聊天窗口的设计3. 添加事件及代码聊天窗口
20、包含有“发送”和“关闭”事件。(1)添加命名空间。因为涉及线程、文件系统和网络的操作,所以添加命名空间如下:using System.Net.Sockets;using System.Net;using System.IO;using System.Threading;(2)添加字段。所添加的字段如下所示:IPAddress myIP;/发送方的IP地址IPAddress toIP;/接受方的IP地址string myName;/方式方的用户名TcpListener tcpListener; /接受方用于TCP监听TcpClient tcpClient;/发送方用于请求与对方连接Socket
21、socket;Thread receThread;/发送信息线程第21页,共76页。8.4 聊天窗口的设计(3)添加构造函数。此构造函数用于接收从主界面传过来的发送方的IP地址,发送方的用户名以及接受方的IP地址。代码如下:public Form2(IPAddress myip,string myname,IPAddress toip) InitializeComponent(); myIP = myip; toIP = toip; myName = myname;第22页,共76页。8.4 聊天窗口的设计(4)添加监听端口并接受信息成员方法。监听3333端口并将接受到的信息转换为字符串类型并
22、显示在textBox1中,代码如下:private void receiveData() tcpListener = new TcpListener(IPAddress.Any, 3333);/新建TcpListener对象 while (true) tcpListener.Start(); /开始监听端口 socket = tcpListener.AcceptSocket();/接受连接请求 byte buffter = new byte1024; /定义缓冲区 while (socket.Receive(buffter) != 0)/接受消息 textBox1.Text += Encodi
23、ng.Default.GetString(buffter); /转换为字符串并显示 socket.Close();/关闭连接 tcpListener.Stop();/停止监听 第23页,共76页。8.4 聊天窗口的设计(5)添加窗体加载事件及其代码。当窗体加载时新建一个线程用于监听端口并接受消息。切换到设计视图,双击Form2,添加其事件代码,代码如下:private void Form2_Load(object sender, EventArgs e) receThread = new Thread(new ThreadStart(receiveData); /新建一个线程用于监听消息 re
24、ceThread.Start(); 第24页,共76页。8.4 聊天窗口的设计(6)添加“发送”按钮事件及其事件代码。“发送”按钮用于和对方建立连接并将信息发送给对方。双击“发送”按钮,其事件代码如下:private void button1_Click(object sender, EventArgs e) tcpClient = new TcpClient(); tcpClient.Connect(toIP, 3333);/建立连接 NetworkStream stream = tcpClient.GetStream();/获取网络流 string strsent = myName + (
25、 + myIP.ToString() + ) + DateTime.Now.ToString() + rn + textBox2.Text+rn;/显示发送者和发送时间 byte buftter = Encoding.Default.GetBytes(strsent);/将要发送的文本转换为字节流 stream.Write(buftter, 0, buftter.Length);/写入网络流中 stream.Close(); /关闭网络流 tcpClient.Close();/关闭连接第25页,共76页。8.4 聊天窗口的设计(7)添加“关闭”按钮事件及其事件代码。“关闭”按钮用于结束线程和关
26、闭窗体等。双击“关闭”按钮,其事件代码如下:private void button2_Click(object sender, EventArgs e) receThread.Abort();/结束线程 if (tcpListener != null) tcpListener.Stop();/停止监听 this.Close();/关闭窗体第26页,共76页。8.4 聊天窗口的设计4. 运行程序按【Ctrl+F5】组合键运行程序。选择“上线”选项,双击自己图标,在弹出的聊天窗口中发送信息,运行的结果如图8.2所示。第27页,共76页。8.5 读者完成部分考虑到篇幅和知识点等因素,以上介绍完成的M
27、yQQ不是很完善并有一些缺陷。读者可将此MyQQ加以修改并完善。(1)在此实例中没有应用数据包内容部分,改写程序将所发送的聊天信息加载到数据包的内容部分并通过UDP服务方式来发送和接受聊天信息。(2)利用TCP方式在聊天窗口中添加文件传输功能。(3)添加聊天记录功能,将所有聊天信息记录下来并在聊天窗口添加读取聊天记录功能。(4)删除“主界面设计”中的“Control.CheckForIllegalCrossThreadCalls = false;”代码,使用线程间通信完成。第28页,共76页。L8.1 项目的创建L1. 网络通信(1)同步方式同步方式是指发送方发送数据包以后,不等接收方响应,就
28、接着发送下一个数据包。(2)异步方式异步方式是指当发送方发送一个数据包以后,一直等到接收方响应后,才可以发送下一个数据包。(3)阻塞套接字阻塞套接字是指在执行此套接字的网络调用时,直到调用成功才返回,否则此套接字就一直阻塞在网络调用上。(4)非阻塞套接字非阻塞套接字是指在执行此套接字的网络调用时,不管是否执行成功,都立即返回。第29页,共76页。L1. 网络通信1. Dns类IP地址是一种普遍应用于因特网、允许不同主机能够相互找到对方的寻址协议。IP地址由4个十进制的数字号码所组成,而每一个号码的值为0255,这虽然解决了网络上计算机的识别问题,但是IP地址不易记忆,因此域名系统(DNS)被开
29、发出来,它专门用于将IP地址转换成有意义的文字,以方便识别记忆。Dns 类是一个静态类,它从 Internet 域名系统 (DNS) 检索关于特定主机的信息。在IPHostEntry 类的实例中返回来自 DNS 查询的主机信息。如果指定的主机在 DNS 数据库中有多个入口,则IPHostEntry 包含多个 IP 地址和别名。Dns类常用方法及说明如表8.1所示。第30页,共76页。L1. 网络通信【例EX8_1】 设计WinForm应用程序用于获取指定主机名的IP地址。 设计步骤:(1)新建WinForm项目新建WinForm项目并命名为“EX8_1”。(2)添加控件并设置属性在Form1的
30、设计视图中,将此窗体调整到适当的大小并将 “Text”属性设为“获取主机IP地址”。从工具箱中拖放1个Button、2个Label和2个TextBox控件到窗体中,按如图8.7所示方式布局控件。label1、label2和button1的Text属性值分别设置为“主机名”、“IP地址:”和“获取”。(3)添加命名空间所要添加的命名空间为“using System.Net;”。第31页,共76页。L1. 网络通信(4)添加事件及代码双击“获取”按钮,其事件代码如下所示:private void button1_Click(object sender, EventArgs e) textBox2.
31、Text = ; try IPHostEntry hostInfo = Dns.GetHostEntry(textBox1.Text.Trim(); foreach (IPAddress ipadd in hostInfo.AddressList) textBox2.Text += ipadd.ToString() + rn; catch (Exception ex) MessageBox.Show(ex.Message.ToString(); 第32页,共76页。L1. 网络通信(5)运行程序按【Ctrl+F5】组合键运行程序,分别输入“”和“”,单击“获取”按钮结果如图8.7和图8.8所示
32、。图8.7 “”的IP地址图8.8 “”的IP地址第33页,共76页。L1. 网络通信2. System.Net.Sockets命名空间System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现。其中Socket类、TcpClient类、TcpListener类、UdpClinet类和NetWorkStrean类较为常用,下面对它们进行简单介绍。(1)Socket类:用于管理连接,实现Berkeley通信端接口,定义绑定、连接网络端点以及传输数据所需的方法,提供处理端点连接传输等细节所需要的功能。We
33、bRequest、TcpClient和UdpClinet等类在内部使用这个类。(2)TcpClient类:允许创建和使用TCP连接,该类创建于Socket类的基础之上并且封装了许多更高级的功能,避免开发人员处理连接操作的相关细节。(3)TcpListener类:允许监听传入的TCP连接请求,倾听来自TCP客户端应用程序的连接要求,封装更高级的功能,使用这个类可以让用户避免处理一些连接服务的细节,以一种比较有效的方式,接收倾听的连接需求。(4)UdpClinet类:提供用户数据报 (UDP) 网络服务。 (5)NetWorkStream类:这个类是从Stream派生出来的,专门用以处理网络形式的
34、数据流,与其他文件数据流的显著区别在于,这个类接收Socket类对象参数,对网络数据进行存取操作。第34页,共76页。L1. 网络通信3. 套接字(Socket)区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。Socket原意是“插座”。通过将这3个参数结合起来,与一个“插座”Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。.NET Framework中的Socket类是Winsock32 API提供的套接字服务的托管代码版本。在大多数情况下,S
35、ocket类方法只是将数据封送到它们的本机Win32副本中,并处理任何必要的安全检查。Socket类支持两种基本模式:同步和异步。在同步模式中,对执行网络操作的函数(如Send和Receive)的调用一直等到操作完成后才将控制权返回给调用程序,而在异步模式中,这些调用立即返回。第35页,共76页。L1. 网络通信在可以使用套接字与远程设备通信之前,必须使用协议和网络地址信息初始化套接字。Socket类的构造函数具有指定套接字用来建立连接的地址族、套接字类型和协议类型的参数等功能。在基于TCP/IP的网络上通信的关键代码如下:Socket socket = new Socket(AddressF
36、amily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);使用UDP而不是TCP进行通信的关键代码如下:Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);参数说明如下:(1)AddressFamily:AddressFamily枚举,用来指定Socket类解析网络地址的标准地址族。(2)SocketType:SocketType枚举,用来指定套接字的类型。(3)ProtocolType:ProtocolTyp
37、e枚举,用来指定在Socket上通信时使用的网络协议。创建Socket类后,既可以开始与远程终结点的连接,也可以接收来自远程设备的连接。第36页,共76页。L1. 网络通信4. Socket类的属性和方法Visual C#通过创建Socket类的实例来实现Socket的托管版本。在Visual C# 中创建完Socket实例后,可以通过此Socket实例的Bind方法绑定到网络中指定的终结点,也可以通过其Connect方法向指定的终结点建立连接。连接创建完毕后,就可以使用其Send或SendTo方法将数据发送到Socket;同样使用其Receive或ReceiveFrom方法从Socket中读
38、取数据。在Socket使用完毕后,请使用其Shutdown方法禁用Socket,并使用Close方法关闭Socket。表8.2和表8.3分别是Socket类中的常用属性和方法及其简要说明。第37页,共76页。L1. 网络通信【例EX8_2】 设计WinForm应用程序,将小写字母转换为大写字母,其中包括客户端和服务端,利用Socket将要转换的小写字母发送给服务端,服务端将接受到的小写字母转换为大写字母并返回给客户端。设计步骤:(1)新建客户端WinForm项目新建WinForm项目并命名为“EX8_2_client”。(2)添加控件并设置属性在Form1的设计视图中,将此窗体调整到适当的大小
39、并将 “Text”属性设为“客户端”。从工具箱中拖放1个Button、2个Label和2个TextBox控件到窗体中,按如图8.9所示方式布局控件。label1、label2和button1的Text属性值分别设置为“发送的字符串:”、“接受并转换为大写的字符串:”和“转换”。第38页,共76页。L1. 网络通信(3)添加命名空间所要添加的命名空间为:using System.Net;using System.Net.Sockets;(4)添加事件及代码双击“转换”按钮,其事件代码如下所示。(5)新建服务端WinForm项目新建WinForm项目并命名为“EX8_2_server”。(6)添加
40、控件并设置属性在Form1的设计视图中将此窗体调整到适当的大小并将 “Text”属性设为“服务端”。从工具箱中拖放1个Button、1个Label和1个TextBox控件到窗体中,按如图8.10所示方式布局控件。label1和button1的Text属性值分别设置为“从客户端接受的字符串:”、“开始监听”。第39页,共76页。L1. 网络通信(7)添加命名空间所要添加的命名空间为:using System.Net;using System.Net.Sockets;(8)添加事件及代码双击“开始监听”按钮,其事件代码如下所示。第40页,共76页。L1. 网络通信(9)运行程序运行此两个程序,单击
41、服务端的“开始监听”按钮,在客户端中输入一些小写字符串并单击的“转换”按钮,运行的结果如图8.9和图8.10所示。 图8.9 客户端 图8.10 服务端第41页,共76页。L1. 网络通信5. TcpClient类TcpClient类为TCP网络服务提供客户端连接。TcpClient类提供了一些简单的方法,用于在同步阻塞模式下通过网络来连接、发送和接收流数据。为使TcpClient连接并交换数据,使用TCP协议创建的TcpListener或Socket必须侦听是否有传入的连接请求。可以使用下面两种方法之一连接到该侦听器:(1)创建一个TcpClient,并调用三个可用的Connect方法之一:
42、TcpClient tcpClient=new TcpClient();/创建一个TcpClient/*使用下面三种方法之一连接到监听器*/tcpClient.Connect (IPAddress, Int32) /使用指定的IP地址和端口号将客户端连接到 TCP 主机tcpClient.Connect (IPAddress, Int32) /使用指定的IP地址和端口号将客户端连接到远程TCP主机tcpClient.Connect (String, Int32) /将客户端连接到指定主机上的指定端口第42页,共76页。L1. 网络通信(2)使用远程主机的主机名和端口号创建TcpClient。此
43、构造函数将自动尝试一个连接。TcpClient client = new TcpClient(hostname, port);要发送和接收数据,可以使用GetStream方法来获取一个NetworkStream。调用NetworkStream的Write和Read方法与远程主机之间发送和接收数据。使用Close方法释放与TcpClient关联的所有资源。TcpClient的常用属性如表8.4所示,常用方法如表8.5所示。第43页,共76页。L1. 网络通信6. TcpListener类TcpListener类从TCP网络客户端监听连接。TcpListener类提供一些简单方法,用于在阻塞同步模
44、式下监听和接受传入连接请求。可使用IPEndPoint、本地IP地址及端口号或者仅使用端口号,来创建TcpListener,创建监听器两种方法如下:(1)使用指定的本地终结点初始化TcpListener类的新实例。 TcpListener tcpListener=new TcpListener (IPEndPoint) (2)使用指定的本地IP地址和端口号,监听是否有传入的连接尝试。TcpListener tcpListener=new TcpListener (IPAddress, Int32) 可使用TcpClient或Socket来连接TcpListener。可以将本地IP地址指定为An
45、y,将本地端口号指定为0(如果希望基础服务提供程序为程序员分配这些值)。如果选择这样做,可在连接套接字后使用 LocalEndpoint 属性来标识已指定的信息。第44页,共76页。L1. 网络通信Start方法用来开始监听传入的连接请求。Start 将对传入连接进行排队,直至调用Stop方法或它已经完成MaxConnections排队为止。可使用 AcceptSocket或AcceptTcpClient从传入连接请求队列提取连接。这两种方法将阻止。如果要避免阻止,可首先使用Pending方法来确定队列中是否有可用的连接请求。TcpListener类的常用属性和方法的如表8.6和表8.7所示。
46、第45页,共76页。L1. 网络通信7. NetworkStream类NetworkStream类提供用于网络访问的基础数据流。NetworkStream类提供在阻塞模式下通过Stream套接字发送和接收数据的方法。可以在同步和异步数据传输时使用NetworkStream类。若要创建NetworkStream,必须提供连接的Socket。也可指定NetworkStream对所提供的Socket具有哪些FileAccess权限。以下是创建NetworkStream的几种方法。(1)为指定的Socket创建NetworkStream类的新实例。NetworkStream networkStream
47、=new NetworkStream (Socket)(2)用指定的Socket 所属权为指定的Socket初始化NetworkStream类的新实例。 NetworkStream networkStream=new NetworkStream (Socket, Boolean) (3)用指定的访问权限为指定的Socket 创建NetworkStream类的新实例。NetworkStream networkStream=new NetworkStream (Socket, FileAccess) (4)用指定的访问权限和指定的Socket所属权为指定的Socket创建NetworkStream
48、类的新实例。NetworkStream networkStream=new NetworkStream (Socket, FileAccess, Boolean) 第46页,共76页。L1. 网络通信将Write和Read方法用于简单的单线程同步阻塞I/O。若要使用不同的线程来处理I/O,则使用BeginWrite和EndWrite方法,或BeginRead和 EndRead方法进行通信。NetworkStream不支持对网络数据流的随机访问。CanSeek属性用于指示流是否支持查找,它的值始终为false;读取Position属性、读取Length属性或者调用 Seek方法都会引发NotSu
49、pportedException异常。NetworkStream类的常用属性和方法如表8.8和表8.9所示。第47页,共76页。L1. 网络通信【例EX8_3】 设计WinForm应用程序发送并接受文件,其中包括发送文件和接受文件两端。设计步骤:(1)新建发送文件端WinForm项目新建WinForm项目并命名为“EX8_3_sendfile”。(2)添加控件并设置属性在Form1的设计视图中将此窗体调整到适当的大小并将 “Text”属性设为“发送文件”。从工具箱中拖放1个Button控件到窗体中,按如图8.11所示方式布局控件。button1的Text属性设置为“选择文件并发送”。(3)添加
50、命名空间所要添加的命名空间为:using System.Net;using System.Net.Sockets;using System.IO;第48页,共76页。L1. 网络通信(4)添加事件及代码双击“选择文件并发送”按钮,其事件代码如下所示。(5)新建接受文件端WinForm项目新建WinForm项目并命名为“EX8_3_receivefile”。(6)设置属性此窗体在运行时是不可见的,Form1的Text属性设置为“接受文件”。(7)添加命名空间所要添加的命名空间为:using System.Net;using System.Net.Sockets;using System.IO;(
51、8)添加事件及代码双击Form1窗体,其事件代码如下所示。第49页,共76页。L1. 网络通信(9)运行程序运行此两个程序,单击发送文件端的“选择文件并发送”按钮,弹出打开文件对话框,选择要发送的文件,此时接受文件端弹出保存文件对话框,输入要保存文件的文件名和后缀名,单击“保存”按钮,则文件接受成功。发送文件端运行的结果如图8.11所示。按【Ctrl+Alt+Del】组合键打开Windows任务管理器,关闭接受端进程,如图8.12所示。 图8.11 发送文件端 图8.12 Windows任务管理器第50页,共76页。L1. 网络通信8. UdpClient类UdpClient类是提供用户数据报
52、(UDP)网络服务。UdpClient类提供了一些简单的方法,用于在阻塞同步模式下发送和接收无连接UDP数据报。因为UDP是无连接传输协议,所以不需要在发送和接收数据前建立远程主机连接。但可以选择使用下面两种方法之一来建立默认远程主机:(1)使用远程主机名和端口号作为参数创建UdpClient类的实例。UdpClient udpClient=new UdpClient(hostname,port)(2)创建UdpClient类的实例,然后调用Connect方法。UdpClient udpClient=new UdpClient();/*使用下面三种方法之一建立默认远程主机*/udpClient
53、.Connect (IPEndPoint) /使用指定的网络终结点建立默认远程主机udpClient.Connect (IPAddress, Int32) /使用指定的IP地址和端口号建立默认远程主机udpClient.Connect (String, Int32) /使用指定的主机名和端口号建立默认远程主机第51页,共76页。L1. 网络通信可以使用在UdpClient中提供的任何一种发送方法将数据发送到远程设备。使用 Receive方法可以从远程主机接收数据。UdpClient类的常用属性和方法如表8.10和表8.11所示。【例EX8_4】 设计WinForm应用程序发送广播信息并接受广播
54、信息,其中包括服务端和接受客户端,服务端用于发送广播信息,而客户端用于接收广播信息。 设计步骤:(1)新建服务端WinForm项目新建WinForm项目并命名为“EX8_4_server”。(2)添加控件并设置属性在Form1的设计视图中,将此窗体调整到适当的大小并将 “Text”属性设为“服务端”。从工具箱中拖放1个Button、1个Label和1个Open File Dialog组件到窗体中,按如图8.11所示进行布局控件。button1的Text属性设置为“选择文件并发送”。第52页,共76页。L1. 网络通信(3)添加命名空间所要添加的命名空间为:using System.Net;us
55、ing System.Net.Sockets;(4)添加事件及代码双击“开始广播”按钮,其事件代码如下所示:private void button1_Click(object sender, EventArgs e) UdpClient udpClient = new UdpClient(); try udpClient.Connect(IPAddress.Parse(55), 5000); Byte sendBytes = Encoding.ASCII.GetBytes(textBox1.Text.Trim(); udpClient.Send(sendBytes, sendBytes.Len
56、gth); /发送信息 udpClient.Close(); catch (Exception ex) Console.WriteLine(ex.Message.ToString(); 第53页,共76页。L1. 网络通信(5)新建客户端WinForm项目新建WinForm项目并命名为“EX8_4_client”。(6)设置属性此窗体在运行时是不可见的,从工具箱中拖放1个Save File Dialog组件到窗体中,Forml的Text属性设置为“接受文件”。(7)添加命名空间所要添加的命名空间为:using System.Net;using System.Net.Sockets;第54页,共
57、76页。L1. 网络通信(8)添加事件及代码双击Form1窗体,其事件代码如下所示:private void Form1_Load (object sender, EventArgs e)UdpClient udpClient = new UdpClient(5000); try IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); Byte receiveBytes = udpClient.Receive(ref RemoteIpEndPoint); /接受消息 string returnData = Encoding
58、.ASCII.GetString(receiveBytes); textBox1.Text = 消息来源IP: + RemoteIpEndPoint.Address.ToString() +端口号:+ RemoteIpEndPoint.Port.ToString()+rn内容:+returnData.ToString(); udpClient.Close(); /释放对象 catch (Exception ex) Console.WriteLine(ex.Message); 第55页,共76页。L1. 网络通信(9)运行程序运行此两个程序,单击客户端的“开始监听”按钮,开始监听广播信息。在服务
59、端中输入“今天下午3点钟有会!”并单击“开始广播”按钮,如图8.13所示。客户端接受消息并显示,如图8.14所示。 图8.13 服务端图8.14 客户端返回第56页,共76页。L8.3 主界面的设计L1. 线程1. 线程简介多线程程序中,在一个线程必须等待的时候,CPU可以运行其他线程而不是等待,这就大大提高了程序的效率。然而,我们也必须认识到线程本身可能存在影响系统性能的不利方面,才能正确使用线程。不利方面主要有:(1)线程也是程序,所以线程需要占用内存,线程越多占用内存也越多。(2)多线程需要协调和管理,所以需要占用CPU时间来跟踪线程。(3)线程之间对共享资源的访问会相互影响,必须解决争
60、用共享资源的问题。 (4)线程太多会导致控制太复杂,最终可能造成很多Bug。第57页,共76页。L1. 线程当启动一个可执行程序时,将创建一个主线程,默认情况下,C#程序具有一个线程。此线程执行程序中以Main方法开始和结束的代码。Main直接或间接执行的每一个命令都由默认线程(或主线程)执行,当Main返回时此线程也将终止。例如打开【EX8_3_server】的“Program.cs”文件,其代码如下:static class Program / / 应用程序的主入口点。 / STAThread static void Main() Application.EnableVisualStyle
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年医用检验与生化分析仪器合作协议书
- 2024客运车租赁合同
- 2024年常用职工劳动协议书范本版
- 二零二四年文化旅游产业发展合作协议2篇
- 2024年度传单发行财务结算合同
- 2024卖房垫资专项借款合同细则3篇
- 钢笔行书字帖
- 医师工作职责
- 2024年度品牌授权经营权转让合同2篇
- 2024年度三方技术协作协议版B版
- 宫腹腔镜在不孕症应用教程课件
- 高中物理-电场的能的性质教学设计学情分析教材分析课后反思
- 【基于PLC的抢答器控制系统设计8800字(论文)】
- 预防压力性损伤的五大要点
- 2023年陕西西安水务(集团)有限责任公司招聘笔试题库含答案解析
- 新药临床试验监查
- 2023年上海市徐汇区高考语文二模试卷及答案解析
- 营销课件第四章stp战略
- GB/T 30146-2023安全与韧性业务连续性管理体系要求
- 延续文化血脉 说课 课件
- 我们对于一棵古松的三种态度
评论
0/150
提交评论