




免费预览已结束,剩余33页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
用c#实现简单通讯程序2006年11月5日 8:13本文介绍了用c#实现的一个类似QQ的局域网通讯程序,当点击最小化程序跑到系统托盘里,双击托盘可以可以显示主页面。程序运行界面如下:托盘里的菜单如下:c#作为微软.Net战略的重要棋子,对网络编程提供了很好的支持和优化。实现起来特别方便,还是看代码吧,已经注释的很清楚了。工程文件放在后面了,需要的可以下载代码如下:using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Data;using System.IO;using System.Net.Sockets;using System.Threading;namespace p2pChat / / MainForm 的摘要说明。 / public class MainForm : System.Windows.Forms.Form private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.TextBox txtIp; private System.Windows.Forms.TextBox txtRecord; private System.Windows.Forms.TextBox txtName; private System.Windows.Forms.Button btnSend; private System.Windows.Forms.TextBox txtContent; private TcpListener tcpLister = new TcpListener(5566); System.Threading.ThreadStart listenPort; System.Threading.Thread lister; private System.Windows.Forms.Label label3; System.Windows.Forms.NotifyIcon NotifyIcon1; /托盘里显示的图标,我用的是QQ里的宠物狗的图标 private Icon img = new Icon(C:OpenPet.ico); System.Windows.Forms.ContextMenu nMenu; / / 必需的设计器变量。 / private System.ComponentModel.Container components = null; public MainForm() / / Windows 窗体设计器支持所必需的 / InitializeComponent(); /不显示最大化按钮 this.MaximizeBox = false; /最小化时不显示在任务栏 this.ShowInTaskbar = false; listenPort += new ThreadStart(this.Listen); lister = new Thread(listenPort); this.Closing += new System.ComponentModel.CancelEventHandler(abortLister); Initializenotifyicon(); / / TODO: 在 InitializeComponent 调用后添加任何构造函数代码 / #region 初始化托盘组件 private void Initializenotifyicon() NotifyIcon1 = new NotifyIcon(); NotifyIcon1.Icon = img; NotifyIcon1.Text = 局域网聊天程序; NotifyIcon1.Visible = true; NotifyIcon1.DoubleClick += new EventHandler(this.showMainForm); MenuItem menuArray = new MenuItem3; menuArray0 = new MenuItem(); menuArray0.Text = 显示主窗口; menuArray0.Click += new EventHandler(this.showMainForm); menuArray0.DefaultItem = true; menuArray1 = new MenuItem(-); menuArray2 = new MenuItem(); menuArray2.Text = 退出; menuArray2.Click += new EventHandler(this.exitSystem); nMenu = new ContextMenu(menuArray); NotifyIcon1.ContextMenu = nMenu; /显示主窗口 private void showMainForm(object sender,System.EventArgs e) this.WindowState = System.Windows.Forms.FormWindowState.Normal; /退出程序 private void exitSystem(object sender,System.EventArgs e) NotifyIcon1.Visible = false; this.Close(); #endregion / / 清理所有正在使用的资源。 / protected override void Dispose( bool disposing ) if( disposing ) if (components != null) components.Dispose(); base.Dispose( disposing ); #region Windows 窗体设计器生成的代码 / / 设计器支持所需的方法 - 不要使用代码编辑器修改 / 此方法的内容。 / private void InitializeComponent() this.label1 = new System.Windows.Forms.Label(); this.txtIp = new System.Windows.Forms.TextBox(); this.txtRecord = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.txtName = new System.Windows.Forms.TextBox(); this.btnSend = new System.Windows.Forms.Button(); this.txtContent = new System.Windows.Forms.TextBox(); this.label3 = new System.Windows.Forms.Label(); this.SuspendLayout(); / / label1 / this.label1.Location = new System.Drawing.Point(16, 232); this.label1.Name = label1; this.label1.Size = new System.Drawing.Size(72, 23); this.label1.TabIndex = 0; this.label1.Text = 目标地址:; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; / / txtIp / this.txtIp.Anchor = (System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right); this.txtIp.Location = new System.Drawing.Point(80, 232); this.txtIp.Name = txtIp; this.txtIp.Size = new System.Drawing.Size(200, 21); this.txtIp.TabIndex = 1; this.txtIp.Text = ; / / txtRecord / this.txtRecord.Anchor = (System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right); this.txtRecord.Location = new System.Drawing.Point(16, 32); this.txtRecord.Multiline = true; this.txtRecord.Name = txtRecord; this.txtRecord.ReadOnly = true; this.txtRecord.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.txtRecord.Size = new System.Drawing.Size(264, 176); this.txtRecord.TabIndex = 4; this.txtRecord.Text = ; / / label2 / this.label2.Location = new System.Drawing.Point(24, 256); this.label2.Name = label2; this.label2.Size = new System.Drawing.Size(48, 23); this.label2.TabIndex = 5; this.label2.Text = 呢 称:; this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; / / txtName / this.txtName.Location = new System.Drawing.Point(80, 256); this.txtName.Name = txtName; this.txtName.Size = new System.Drawing.Size(88, 21); this.txtName.TabIndex = 6; this.txtName.Text = ; / / btnSend / this.btnSend.Location = new System.Drawing.Point(200, 256); this.btnSend.Name = btnSend; this.btnSend.Size = new System.Drawing.Size(64, 23); this.btnSend.TabIndex = 0; this.btnSend.Text = 发 送; this.btnSend.Click += new System.EventHandler(this.btnSend_Click); / / txtContent / this.txtContent.Anchor = (System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right); this.txtContent.Location = new System.Drawing.Point(16, 288); this.txtContent.Multiline = true; this.txtContent.Name = txtContent; this.txtContent.Size = new System.Drawing.Size(264, 152); this.txtContent.TabIndex = 8; this.txtContent.Text = ; / / label3 / this.label3.Anchor = (System.Windows.Forms.AnchorStyles)(System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right); this.label3.Location = new System.Drawing.Point(16, 8); this.label3.Name = label3; this.label3.Size = new System.Drawing.Size(100, 16); this.label3.TabIndex = 9; this.label3.Text = 聊天记录:; this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; / / MainForm / this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(292, 453); this.Controls.Add(this.label3); this.Controls.Add(this.txtContent); this.Controls.Add(this.btnSend); this.Controls.Add(this.txtName); this.Controls.Add(this.label2); this.Controls.Add(this.txtRecord); this.Controls.Add(this.txtIp); this.Controls.Add(this.label1); this.Name = MainForm; this.Text = 局域网聊天程序; this.Load += new System.EventHandler(this.MainForm_Load); this.ResumeLayout(false); #endregion / / 应用程序的主入口点。 / STAThread static void Main() Application.Run(new MainForm(); /开始监听 private void Listen() try tcpLister.Start(); while(true) Socket s = tcpLister.AcceptSocket(); Byte stream = new Byte80; int i = s.Receive(stream); string message = System.Text.Encoding.UTF8.GetString(stream); this.txtRecord.AppendText(message); catch(System.Security.SecurityException) MessageBox.Show(防火墙安全错误!,错误,MessageBoxButtons.OK,MessageBoxIcon.Exclamation); catch(System.Exception) /this.txtRecord.AppendText(已停止监听!); private void abortLister(object sender,System.ComponentModel.CancelEventArgs e) this.tcpLister.Stop(); /发送 private void btnSend_Click(object sender, System.EventArgs e) if(this.txtContent.Text=) MessageBox.Show(不能发送空信息!,提示,MessageBoxButtons.OK,MessageBoxIcon.Exclamation); else this.Send(); /发送消息 private void Send() try string msg = this.txtName.Text+ (+System.DateTime.Now.ToString()+)rn+this.txtContent.Text+rn; TcpClient client = new TcpClient(this.txtIp.Text,5566); NetworkStream sendStream = client.GetStream(); StreamWriter writer = new StreamWriter(sendStream); writer.Write(msg); writer.Flush(); sendStream.Close(); client.Close(); this.txtRecord.AppendText(msg); this.txtContent.Clear(); catch(System.Exception) this.txtRecord.AppendText(目标计算机拒绝连接请求!rn); private void MainForm_Load(object sender, System.EventArgs e) this.txtRecord.AppendText(正在监听.rn); lister.Name = 监听本地端口; lister.Start(); 套接字编程(二)2006年11月4日 17:39用到IPEndPoint类的时候就不可避免地涉及到计算机IP地址,System.Net命名空间中有两种类可以得到IP地址实例: IPAddress类:IPAddress 类包含计算机在 IP 网络上的地址。其Parse方法可将 IP 地址字符串转换为 IPAddress 实例。下面的语句创建一个 IPAddress 实例: IPAddress myIP = IPAddress.Parse(); 需要知道的是:Socket 类支持两种基本模式:同步和异步。其区别在于:在同步模式中,按块传输,对执行网络操作的函数(如 Send 和 Receive)的调用一直等到所有内容传送操作完成后才将控制返回给调用程序。在异步模式中,是按位传输,需要指定发送的开始和结束。同步模式是最常用的模式,我们这里的例子也是使用同步模式。下面看一个完整的例子,client向server发送一段测试字符串,server接收并显示出来,给予client成功响应。 /client端 using System; using System.Text; using System.IO; using System.Net; using System.Net.Sockets; namespace socketsample class Class1 static void Main() try int port = 2000; string host = ; IPAddress ip = IPAddress.Parse(host); IPEndPoint ipe = new IPEndPoint(ip, port);/把ip和端口转化为IPEndPoint实例 Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);/创建一个Socket Console.WriteLine(Conneting.); c.Connect(ipe);/连接到服务器 string sendStr = hello!This is a socket test; byte bs = Encoding.ASCII.GetBytes(sendStr); Console.WriteLine(Send Message); c.Send(bs, bs.Length, 0);/发送测试信息 string recvStr = ; byte recvBytes = new byte1024; int bytes; bytes = c.Receive(recvBytes, recvBytes.Length, 0);/从服务器端接受返回信息 recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes); Console.WriteLine(Client Get Message:0, recvStr);/显示服务器返回信息 c.Close(); catch (ArgumentNullException e) Console.WriteLine(ArgumentNullException: 0, e); catch (SocketException e) Console.WriteLine(SocketException: 0, e); Console.WriteLine(Press Enter to Exit); Console.ReadLine(); /server端 using System; using System.Text; using System.IO; using System.Net; using System.Net.Sockets; namespace Project1 class Class2 static void Main() try int port = 2000; string host = ; IPAddress ip = IPAddress.Parse(host); IPEndPoint ipe = new IPEndPoint(ip, port); Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);/创建一个Socket类 s.Bind(ipe);/绑定2000端口 s.Listen(0);/开始监听 Console.WriteLine(Wait for connect); Socket temp = s.Accept();/为新建连接创建新的Socket。 Console.WriteLine(Get a connect); string recvStr = ; byte recvBytes = new byte1024; int bytes; bytes = temp.Receive(recvBytes, recvBytes.Length, 0);/从客户端接受信息 recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes); Console.WriteLine(Server Get Message:0,recvStr);/把客户端传来的信息显示出来 string sendStr = Ok!Client Send Message Sucessful!; byte bs = Encoding.ASCII.GetBytes(sendStr); temp.Send(bs, bs.Length, 0);/返回客户端成功信息 temp.Close(); s.Close(); catch (ArgumentNullException e) Console.WriteLine(ArgumentNullException: 0, e); catch (SocketException e) Console.WriteLine(SocketException: 0, e); Console.WriteLine(Press Enter to Exit); Console.ReadLine(); 上面的例子是用的Socket类,System.Net.Socket命名空间还提供了两个抽象高级类TCPClient和UDPClient和用于通讯流处理的NetWorkStream,让我们看下例子客户端 TcpClient tcpClient=new TcpCLient(主机IP,端口号); NetworkStream ns=tcp.Client.GetStream(); 服务端 TcpListener tcpListener=new TcpListener(监听端口); tcpListener.Start(); TcpClient tcpClient=tcpListener.AcceptTcpClient(); NetworkStream ns=tcpClient.GetStream(); 服务端用TcpListener监听,然后把连接的对象实例化为一个TcpClient,调用TcpClient.GetStream()方法,返回网络流实例化为一个NetworlStream流,下面就是用流的方法进行Send,Receive如果是UdpClient的话,就直接UdpClient实例化,然后调用UdpClient的Send和Receive方法,需要注意的事,UdpClient没有返回网络流的方法,就是说没有GetStream方法,所以无法流化,而且使用Udp通信的时候,不要服务器监听。现在我们大致了解了.Net Socket通信的流程,下面我们来作一个稍微复杂点的程序,一个广播式的C/S聊天程序。客户端设计需要一个1个ListBox,用于显示聊天内容,一个TextBox输入你要说的话,一个Button发送留言,一个Button建立连接。点击建立连接的Button后出来一个对话框,提示输入连接服务器的IP,端口,和你的昵称,启动一个接受线程,负责接受从服务器传来的信息并显示在ListBox上面。服务器端2个Button,一个启动服务,一个T掉已建立连接的客户端,一个ListBox显示连接上的客户端的Ip和端口。比较重要的地方是字符串编码的问题,需要先把需要传送的字符串按照UTF8编码,然后接受的时候再还原成为GB2312,不然中文显示会是乱码。还有一个就是接收线程,我这里简单写成一个While(ture)循环,不断判断是否有信息流入,有就接收,并显示在ListBox上,这里有问题,在.Net2.0里面,交错线程修改窗体空间属性的时候会引发一个异常,不可以直接修改,需要定义一个委托来修改。 当客户端需要断开连接的时候,比如点击窗体右上角的XX,就需要定义一个this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Closing);(.Net2.0是FormClosing系统事件),在Closing()函数里面,发送Close字符给服务端,服务器判断循环判断所有的连接上的客户端传来的信息,如果是以Close开头,断开与其的连接。看到这里,读者就会问了,如果我在聊天窗口输入Close是不是也断开连接呢?不是的,在聊天窗口输入的信息传给服务器的时候开头都要加上Ip信息和昵称,所以不会冲突。套接字编程(一)2006年11月4日 17:37首先从原理上解释一下采用Socket接口的网络通讯,这里以最常用的C/S模式作为范例,首先,服务端有一个进程(或多个进程)在指定的端口等待客户来连接,服务程序等待客户的连接信息,一旦连接上之后,就可以按设计的数据交换方法和格式进行数据传输。客户端在需要的时刻发出向服务端的连接请求。这里为了便于理解,提到了一些调用及其大致的功能。使用socket调用后,仅产生了一个可以使用的socket描述符,这时还不能进行通信,还要使用其他的调用,以使得socket所指的结构中使用的信息被填写完。
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 仓储物流信息化管理与运输服务合同
- 跨国公司境内股权转让及税务筹划协议
- 生态柴油购销合同范本与规范
- 成都租赁合同(含租客租后押金退还)
- 民宿民宿风格改造装修合同
- 互联网保险保本投资协议
- 北京二手房交易税费减免咨询与代理合同
- 餐饮店拆伙协议及员工安置合同
- 时尚购物广场门面房租赁与品牌合作合同
- 肿瘤的影像学诊断
- 广东省广州市天河区2023-2024学年八年级下学期期末历史试卷(含答案)
- 2025-2030年中国有机肥料行业市场投资分析及未来发展趋势预测研究报告
- AI技术赋能中小学教学模式创新与实践研究
- 山西焦煤集团招聘笔试题库2025
- 2025汾西矿业井下操作技能人员招聘300人(山西)笔试参考题库附带答案详解析
- 健康吃肉课件
- 《国家粮食和物资储备局垂直管理系统重大生产安全事故隐患判定标准(试行)》解读与培训
- 2025至2030年中国速冻豆角行业投资前景及策略咨询报告
- (2025)交管12123驾驶证学法减分题库含答案大全
- 学校食堂合同范本模板
- 2025年卫生类事业单位(医学基础知识)公开招聘必刷题库(300题)
评论
0/150
提交评论