版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
PAGEPAGEIPAGEI简单QQ聊天系统摘要目前网络通讯是计算机用户进行交流最普遍的方式,各种各样基于网络的应用也随之诞生,比如“腾讯QQ”——一款基于Internet的即时通信(IM)软件,它使人们能随时在网上与其他用户交换消息,为网络用户提供一个即时交流聊天的平台。本设计主要是仿照QQ聊天系统,实现两个用户进行即时交谈的功能,为进一步开发即时通信技术应用奠定基础。该程序设计采用了客户端/服务器模式,基于TCP面向连接的方式,实现用户之间一对一的数据传输。用到的关键技术有套接字Socket、单线程技术等,是在VisualC#2008语言下进行编程的。本论文将介绍该聊天程序的相关功能、特点、设计思路及其使用方法,通过相关的插图详细介绍整个程序的开发过程及其具体实现,并总结开发过程中的经验等。关键词即时通信、套接字Socket、单线程目录第1章绪论 11.1 引言 11.1.1编写目的 11.1.2 背景 11.2 课题意义 11.3 研究现状 2第2章系统分析概述 32.1 可行性研究 32.1.1 技术可行性 32.1.2 经济可行性 32.1.3 操作可行性 32.2 系统分析 32.2.1 功能要求 32.2.2 系统流程图 3第3章总体设计 53.1 体系结构设计 53.2 功能简介 53.2.1 服务器工作流程 53.2.2 客户端工作流程 63.3 系统特点 6第4章详细设计 74.1 系统的开发工具 74.2 服务器模块设计 74.2.1服务器登录模块 74.2.2服务器聊天模块 9 聊天模块控件属性表 10 聊天模块代码 114.3 客户端模块设计 174.3.1客户端登录模块 174.3.2客户端聊天模块 19结论 28参考文献 29绪论引言随着互联网应用越来越丰富,以快速、交互、简便为代表的即时通讯工具,已经成为当前网络用户最喜爱的网络沟通工具。作为即时通讯工具最具增长潜力之一的聊天软件,不仅在基础应用方面,还是产品扩展应用方面都将有质的飞跃,极大程度上方便了处于在世界各地的友人之间的相互联系。特别是在近几年,即时通讯工具已经成为一个集互动交流、休闲娱乐、信息管理为一体的多元化互联网应用平台。总之,聊天软件的出现给人们彼此之间的沟通带来了无比的方便,人们可以通过聊天软件建立深刻的友情,它必定会成为人们网络生活不可缺少的一部分。1.1.1编写目的综合运用计算机网络应用编程中的TCP网络通信协议以及Socket套接字等知识,以VisualC#作为开发平台,编写一个单线程聊天程序。本程序需要在一台计算机上运行服务器端程序,然后就可以在同一网络的另外一台计算机上运行客户端程序,登录到服务器上,从而实现服务器与用户之间的即时聊天、发送图片等功能。背景◆项目名称:简单的单线程QQ聊天系统◆项目用户:***◆开发者:***课题意义一直以来,空间上的距离都是人们彼此相互交流的最大障碍。以前人们的信息交流是通过电话、信件、电报等手段,由于功能的局限给收发双方带来了很多不便。所以更加即时的直观的使人们能在网上识别在线用户并与他们实时交换消息的即时通信技术应运而生,它是电子邮件发明以来迅速崛起的在线通讯方式,为网络用户提供一个实时交流聊天的平台。而且即时通信和社会化网络、统一通信、在线协同三大技术热点的关系将越来越密切,已经构成融合发展的趋势,因此即时通信技术的应用将越来越广泛,越来越普遍。研究现状即时消息系统[1](InstantMessenger,IM)是一种在后PC时代兴起的,以Internet网络为基础的,允许交互双方即时地传送文字、语音、视频等信息,能够跟踪网络用户在线状态的网络应用软件。即时消息系统产生有着深刻的社会原因:人们都有渴望社交,获得社会尊重、实现自我的需求,这正是即时消息软件风行的原动力,而物质文明的日益发达所带来副作用,又使得人们习惯与周围的人保持距离,以致人们更愿意对陌生人敞开心扉,在网络中可以跨越年龄、身份、行业、地域的限制,达到人与人、人与信息之间的零距离交流。从这点上讲,即时消息系统的出现改变了人们的沟通方式和交友文化,大大拓展了个人生活交流的空间。国内最为流行的即时消息软件是OICQ(简称QQ)。它以良好的中文界面和不断增强的功能形成了一定的QQ网络文化。该软件是由腾讯公司于1999年2月自主开发的基于Internet的即时消息系统。腾讯QQ目前已成为中国最主要的即时消息服务网络软件。作为一种即时消息工具,QQ支持显示好友在线、即时传送文字、语音和文件等功能。QQ还与无线寻呼、GSM短信息、IP电话网互联,为用户提供互联网短信及信息增值服务。腾讯QQ开发和拓展统一、高速、丰富的互联网应用平台、在线广告业务、移动通信业务、ISP及IP电话合作业务、企业商用即时消息服务、在线客户支持及在线呼叫业务。系统分析概述可行性研究技术可行性随着互联网应用越来越丰富,以快速、交互、简便为代表的即时通讯工具,已经成为当前网络用户最喜爱的网络沟通工具。本系统是一个使用套接字Socket编程,采用其中的TCP面向连接方式的简单的聊天工具,具有很强的实用价值。经济可行性开发本系统能够使人们之间的交流带来极大的方便,而且所用的人力、物力、技术、资金等的花费不大,所以今后获得的经济效益一定会大于开发成本。操作可行性本开发系统操作步骤简单,运行时只要在登录时输入服务器信息以及自己的昵称就可以进入聊天程序,然后就可以与服务器进行信息交流。系统分析功能要求ⅰ.客户端登录时输入的服务器信息必须与服务端一致。ⅱ.用户与服务器之间的信息发送,是本程序需要实现的最基本的功能。ⅲ.在C/S模式中,服务器和客户端是相互依赖的。服务器启动以后,客户端才能连接上服务器,如果服务器没有启动,那么用户和服务器不能连接而且客户端或服务器任意一方断开连接,对方都会能接收到通知消息。系统流程图登录登录服务器启动监听器等待接受客户端连接读取客户端数据向客户端写数据断开连接登录客户端准备Socket连接服务器向服务器写数据读取服务器数据断开连接返回返回总体设计体系结构设计通常的通信工具,都采用客户机/服务器(C/S)体系结构,C/S结构是这样的一种结构:它包括一个客户机(或前端),一个服务器(或称后端),客户机的作用是访问和处理远程服务器上的数据,服务器的作用是接收和处理客户机的数据请求。另外它的服务器端还可以将信息集中起来,任何客户机都可以通过访问服务器而获得所需的信息。Client/Server模型最终可归结为一种“请求/应答”关系。一个请求总是首先被客户发出,然后服务器总是被动地接收请求,返回客户需要的结果。在客户发出一个请求之前,服务进程一直处于休眠状态。一个客户提出请求后,服务进程被“唤醒”并且为客户提供服务,对客户的请求做出所需要的应答。如下图所示:服务器客户端服务器客户端在服务器启动以后,等待客户端的连接,当有客户连接上来以后,服务器监听到客户端的端口号,然后客户端显示连接成功到服务器,以告知服务器自己在线,然后服务器和客户端就可以进行信息交流。如果服务器不在线,则客户端会提示用户退出。功能简介本聊天程序提供了服务器与客户端的一对一连接,客户端必须在服务器启动以后才能连接成功。用户登录以后聊天室的客户端会显示用户的登录昵称和在线时间,还可以与服务器进行即时聊天、发送图片等。服务器工作流程⑴.服务器输入IP地址和端口号,点击“登录”按钮,服务器登录聊天室。⑵.点击控制台的“启动”按钮,服务器开始侦听,等待客户端连接。⑶.如果有用户连接上来,服务器可以与用户进行信息传输、发送图片等。⑷.点击“断开”按钮,服务器将停止端口侦听,并通知用户。⑸.点击“退出”按钮,服务器将退出聊天程序。客户端工作流程⑴.用户输入服务器的IP地址和端口号以及自己的昵称后,点击“登录”按钮,用户将登录聊天室。⑵.点击控制台的“连接”按钮,如果连接成功,用户将通过刚刚输入的昵称连接上服务器,并通知服务器连接成功。⑶.连接成功后,用户可以与服务器进行信息传输、发送图片等。⑷.当用户点击“断开”按钮,客户端将断开与服务器的连接,并通知服务器断开连接。⑸.用户点击“退出”按钮时,将退出聊天程序。系统特点界面设计美观友好。规范、完整的基础信息设置。能够即时进行通信聊天。系统运行稳定、安全可靠。详细设计系统的开发工具4.1.1开发环境--VisualStudio是微软公司出品的一款大型应用软件,是一套完整的开发工具集,它主要用于生成ASP.NETWeb应用程序、XMLWebServices、桌面应用程序和移动应用程序。4.1.2C#(CSharp)是微软(Microsoft)为.NETFramework量身订做的程序语言,C#拥有C/C++的强大功能以及VisualBasic简易使用的特性,是第一个组件导向(Component-oriented)的程序语言,和C++与Java一样亦为对象导向(object-oriented)程序语言。服务器模块设计4.2.1服务器登录模块登录模块界面服务器进入登录界面(如图4-2-1)后,设置IP地址和端口号,点击“登录”按钮,系统将验证输入的服务器信息是否合法,如果服务器信息合法则跳转到聊天室,否则将弹出错误提示窗口(如图4-2-2)。如果未设置服务器信息,则弹出信息提示窗口(如图4-2-3);点击“重置”按钮,服务器信息图4-2-图4-2-2图4-2-3登录模块控件属性表控件属性值控件成员变量TextBoxtxtIPTextBoxtxtPortButton登录btnLogButton重置btnResent登录模块代码//登录聊天室privatevoidbtnLog_Click(objectsender,EventArgse){if(txtIP.Text==""||txtPort.Text==""){MessageBox.Show("请输入IP地址或端口号!","提示信息",MessageBoxButtons.OK,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1);return;}else{try{IPAddressipadd=IPAddress.Parse(this.txtIP.Text);intport=Convert.ToInt32(this.txtPort.Text);tab2.Visible=true;tab1.Visible=false;this.btnImgFile.Enabled=false;this.Text="服务器"+DateTime.Now.ToString()+""+DateTime.Now.DayOfWeek.ToString();richTextBox1.AppendText("System:服务器已进入聊天室!<-"+DateTime.Now.ToLongTimeString()+"->\r\n");stringSerIp=txtIP.Text.ToString();stringSerPort=txtPort.Text.ToString();labip.Text="IP地址:"+""+SerIp+"";labport.Text="端口号:"+""+SerPort;}catch(Exception){MessageBox.Show("您输入的IP地址或端口号不正确,\n请重新输入!","错误",MessageBoxButtons.OK,MessageBoxIcon.Error);}}}//重置服务器信息privatevoidbtnResent_Click_1(objectsender,EventArgse){txtIP.Clear();txtPort.Clear();}4.2.2服务器聊天模块聊天模块界面服务器进入聊天室后,状态栏显示服务器登录时输入的IP地址和端口号。点击“启动”按钮,服务器开始监听,如果有用户连接上来,服务器可以与用户进行聊天(如图4-2-4另外聊天室的工具栏还有一些辅助按钮,点击“背景颜色”按钮,设置聊天记录的背景颜色(如图4-2-5);点击“隐藏窗口”按钮,隐藏聊天程序;点击“帮助”按钮,弹出帮助对话框(如图4-2-6图4-2-图4-2-图4-2-聊天模块控件属性表控件属性值控件成员变量Button启动(&L)btn_startButton断开(&S)btn_stopButton退出(&E)btn_ExitButton背景颜色(&C)btnColoButton隐藏窗口(&Y)btnYingButton帮助(&H)btnHelpedButton关于(&A)btnAboutButton发送图片btnImgFileButton清屏btnClearButton发送btn_sendButton取消btnRestRichTextBoxrichTextBox1RichTextBoxtxt1_sendinfoLabelIP地址:labipLabel端口号:labport聊天模块代码publicpartialclassChatServer:Form{privateOpenFileDialogopenfiledialog=newOpenFileDialog();privateSaveFileDialogsavefiledialog=newSaveFileDialog();privatebyte[]img;//传输图片用字节数组privateintimgflag=0;privateFileStreamfstream;publicdelegatevoidUpdateRichTextBox(stringmsg);//异步委托代理publicdelegatevoidUpdateImg(Streams);privateSocketsocket;//服务器端套接字privateSocketclientSocket;//客户端连接套接字privateThreadthread;//启动服务器,开始监听privatevoidbtn_start_Click(objectsender,EventArgse){try{IPAddressip=IPAddress.Parse(this.txtIP.Text);IPEndPointserver=newIPEndPoint(ip,Int32.Parse(this.txtPort.Text));//创建服务器套接字socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);socket.Bind(server);//绑定端口号socket.Listen(10);thread=newThread(newThreadStart(AcceptMessage));thread.Start();//开始监听this.Text="服务器Taking";richTextBox1.Clear();richTextBox1.AppendText("System:服务器已启动!<-"+DateTime.Now.ToLongTimeString()+"->\r\n");btnImgFile.Enabled=true;btn_start.Enabled=false;btn_stop.Enabled=true;}catch(Exceptionex){MessageBox.Show("服务器:"+ex.Message);this.btn_start.Enabled=true;}}//接收客户端信息publicvoidAcceptMessage()//异步接收信息后台线程方法{this.clientSocket=socket.Accept();this.richTextBox1.Clear();richTextBox1.AppendText("System:服务器连接成功!<-"+DateTime.Now.ToLongTimeString()+"->\r\n");while(true){try{if(this.clientSocket==null||this.clientSocket.Connected==false)break;NetworkStreamnetStream=newNetworkStream(this.clientSocket);//通过clientSocket对象获取NetworkStream对象//得到一条消息的长度byte[]dataSize=newbyte[4];netStream.Read(dataSize,0,4);intsize=System.BitConverter.ToInt32(dataSize,0);//循环接收直到一条完整的消息全部读入到字节数组中byte[]message=newbyte[size];intdataleft=size;intstart=0;if(size>0){while(dataleft>0){intrecv=netStream.Read(message,start,dataleft);start+=recv;dataleft-=recv;}if(message[0]==101)//101代表传输图片{MemoryStreamms=newMemoryStream(message,1,message.Length-1);richTextBox1.BeginInvoke(newUpdateImg(ViewImg),newobject[]{ms});}else//默认进行普通传输{stringMsg=System.Text.Encoding.Unicode.GetString(message,1,message.Length-1);this.richTextBox1.BeginInvoke(newUpdateRichTextBox(UpdateMessage),newobject[]{Msg});}}Thread.Sleep(100);}catch(System.Net.Sockets.SocketExceptionse){MessageBox.Show("服务器:"+se.Message);}}}//点击“发送”按钮privatevoidbtn_send_Click(objectsender,EventArgse){if(txt1_sendinfo.Text==""){MessageBox.Show("请先输入内容!");txt1_sendinfo.Clear();txt1_sendinfo.Focus();return;}if(imgflag==1){//发送图片时byte[]imgSize=newbyte[4];//将32位整数值转换为字节数组imgSize=System.BitConverter.GetBytes(img.Length+1);//其中加1是因为后面了一个101做分隔符try{NetworkStreamnetStream=newNetworkStream(clientSocket);netStream.Write(imgSize,0,4);netStream.WriteByte(101);//分隔符netStream.Write(img,0,img.Length);netStream.Flush();this.richTextBox1.SelectionColor=Color.SteelBlue;this.richTextBox1.AppendText("服务器<-"+DateTime.Now.ToLongTimeString()+"->:\r\n");this.richTextBox1.SelectionStart=this.richTextBox1.Text.Length;Clipboard.SetDataObject(Image.FromStream(fstream));richTextBox1.Paste();this.richTextBox1.SelectionColor=Color.SteelBlue;this.richTextBox1.AppendText("\n");fstream.Flush();fstream.Close();//此流必须在这里才可以消除txt1_sendinfo.Paste();this.richTextBox1.SelectionStart=this.richTextBox1.Text.Length;this.richTextBox1.Focus();this.txt1_sendinfo.Text="";this.txt1_sendinfo.Focus();imgflag=0;//复原return;//不执行后面的传输文本信息}catch(System.Exceptionex){MessageBox.Show("服务器:"+ex.Message);}}//发送文本信息时this.richTextBox1.SelectionColor=Color.SteelBlue;stringstr="服务器<-"+DateTime.Now.ToLongTimeString()+"->:\r\n"+txt1_sendinfo.Text;inti=str.Length;if(i==0){return;}else{//因为str为Unicode编码,每个字符占2个字节,所以实际字节数应为字符个数*2i*=2;}byte[]dataSize=newbyte[4];//将32位整数值转换为字节数组dataSize=System.BitConverter.GetBytes(i+1);//其中加1是因为后面写了一个1做分隔符byte[]sendbytes=System.Text.Encoding.Unicode.GetBytes(str);try{NetworkStreamnetStream=newNetworkStream(clientSocket);netStream.Write(dataSize,0,4);netStream.WriteByte(1);//分隔符netStream.Write(sendbytes,0,sendbytes.Length);netStream.Flush();richTextBox1.SelectionColor=Color.SteelBlue;this.richTextBox1.AppendText(str+"\n");this.richTextBox1.SelectionStart=this.richTextBox1.Text.Length;this.richTextBox1.Focus();this.txt1_sendinfo.Rtf="";this.txt1_sendinfo.Focus();}catch(System.Exceptionex){MessageBox.Show("服务器:"+ex.Message);}}//断开连接privatevoidbtn_stop_Click(objectsender,EventArgse){socket.Close();thread.Abort();thread.Join(10);this.btn_start.Enabled=true;btn_stop.Enabled=false;this.btnImgFile.Enabled=false;this.Text="服务器"+DateTime.Now.ToString()+""+DateTime.Now.DayOfWeek.ToString();this.richTextBox1.AppendText("System:服务器断开连接!<-"+DateTime.Now.ToLongTimeString()+"->\r\n");}//接收文本privatevoidUpdateMessage(stringstrmsg)//将异步接收到的信息显示在富文本框里{this.richTextBox1.SelectionColor=Color.LightCoral;this.richTextBox1.AppendText(strmsg+"\n");this.richTextBox1.SelectionStart=this.richTextBox1.Text.Length;this.richTextBox1.Focus();this.txt1_sendinfo.Focus();}//接收图片信息privatevoidViewImg(Streams)//将异步接收到的信息显示在富文本框里{richTextBox1.SelectionStart=richTextBox1.Text.Length;richTextBox1.SelectionColor=Color.LightCoral;richTextBox1.AppendText("服务器接收图片<-"+DateTime.Now.ToLongTimeString()+"->:\r\n");Clipboard.SetDataObject(Image.FromStream(s));//利用剪切板richTextBox1.Paste();richTextBox1.SelectionColor=Color.LightCoral;richTextBox1.AppendText("\n");richTextBox1.SelectionStart=richTextBox1.Text.Length;richTextBox1.Focus();txt1_sendinfo.Focus();}//上传图片文件中的图片privatevoidbtnImgFile_Click(objectsender,EventArgse){openfiledialog.Filter="所有文件(*.*)|*.*|位图文(*.bmp)|*.bmp|文件(*.jpg)|*.jpg|文件(*.gif)|*.gif";if(openfiledialog.ShowDialog()==DialogResult.OK){Stringstrpath=openfiledialog.FileName;fstream=newFileStream(strpath,FileMode.Open);BinaryReaderbreader=newBinaryReader(fstream);img=breader.ReadBytes((int)fstream.Length);Clipboard.SetDataObject(Image.FromStream(fstream));txt1_sendinfo.Paste();imgflag=1;}}//退出聊天室privatevoidbtn_Exit_Click(objectsender,EventArgse){if(btn_stop.Enabled!=true){this.Close();Application.Exit();}else{MessageBox.Show("请先断开连接!");return;}}//取消发送privatevoidbtnRest_Click(objectsender,EventArgse){txt1_sendinfo.Clear();}//清屏privatevoidbtnClear_Click(objectsender,EventArgse){this.richTextBox1.Clear();}}客户端模块设计4.3.1客户端登录模块界面客户端进入登录界面(如图4-3-1)后,输入服务器IP地址和端口号以及自己的昵称,点击“登录”按钮,系统将验证输入的服务器信息是否合法,如果合法则跳转到聊天室,否则弹出错误对话框(如图4-3-2)。如果未输入服务器信息则弹出提示提示(如图4-3-3).;如果未输入昵称则弹出提示信息提示(如图4-3-4);点击“重置”按钮,服务器信息和昵称则被清空。图4-3-1图4-3图4-3图4-3-4提示输入昵称登录模块控件属性表控件属性值控件成员变量TextBoxtxt_IPTextBoxtxt_PortTextBoxtxtNameButton登录btnLogButton重置btnResent客户端登录模块代码//登录聊天室privatevoidbtnLog_Click(objectsender,EventArgse){if(txt_IP.Text==""||txt_Port.Text==""){MessageBox.Show("服务器信息不能为空!","提示信息",MessageBoxButtons.OK,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1);return;}if(txtName.Text==""){MessageBox.Show("请输入您的呢称!","提示信息",MessageBoxButtons.OK,MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1);return;}else{try{IPAddressipadd=IPAddress.Parse(this.txt_IP.Text);intport=Convert.ToInt32(this.txt_Port.Text);userName=txtName.Text.ToString();tab1.Visible=false;tab2.Visible=true;this.btnImgFile.Enabled=false;this.Text=""+userName+""+DateTime.Now.ToString()+""+DateTime.Now.DayOfWeek.ToString();richTextBox1.AppendText("System:"+userName+"已进入聊天室!<-"+DateTime.Now.ToLongTimeString()+"->\r\n");stringSerIp=txt_IP.Text.ToString();stringSerPort=txt_Port.Text.ToString();lbSerIp.Text="IP地址:"+""+SerIp+"";lbSerPort.Text="端口号:"+""+SerPort;}catch(Exception){MessageBox.Show("您输入的服务器信息不合法,\n请重新输入!","错误",MessageBoxButtons.OK,MessageBoxIcon.Error);}}}//重置服务器信息和昵称privatevoidbtnResent_Click(objectsender,EventArgse){txt_IP.Clear();txt_Port.Clear();txtName.Clear();}4.3.2客户端聊天聊天模块界面用户进入聊天室后,状态栏显示服务器信息和昵称。点击“连接”按钮,如果服务器已启动,用户连接上聊天室并与服务器进行聊天(如图4-3-5)另外聊天室的工具栏还有一些辅助按钮,点击“背景颜色”按钮,设置聊天记录的背景颜色(如图4-3-6);点击“隐藏窗口”按钮,隐藏聊天程序;点击“帮助”按钮,弹出帮助对话框(如图4-3-图4-3-5客户端聊天界面图4-3-6设置背景颜色图4-3-8帮助对话框聊天模块控件属性表控件属性值控件成员变量Button连接(&L)btn_reqButton断开(&S)btn_closeButton退出(&E)btn_ExitButton背景颜色(&C)btnColoButton隐藏窗口(&Y)btnYingButton帮助(&H)btnHelpedButton关于(&A)btnAboutButton发送图片btnImgFileButton清屏btnClearButton发送btn_sendButton取消btnRestRichTextBoxrichTextBox1RichTextBoxtxt2_sendLabelIP地址:lbSerIpLabel端口号:lbSerPort聊天室模块代码publicpartialclassChatClient:Form{privateOpenFileDialogopenfiledialog=newOpenFileDialog();privateSaveFileDialogsavefiledialog=newSaveFileDialog();privatebyte[]img;//保存传图片时的字节数组privateintimgflag=0;privateFileStreamfstream;publicdelegatevoidUpdateMessage(stringmsg);publicdelegatevoidUpdateImg(Streams);privateSocketsocket;privateThreadthread;publicstringuserName;//与服务器连接privatevoidbtn_req_Click(objectsender,EventArgse){try{IPAddressip=IPAddress.Parse(this.txt_IP.Text);IPEndPointserver=newIPEndPoint(ip,Int32.Parse(this.txt_Port.Text));//创建客户端套接字socket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);socket.Connect(server);//连接thread=newThread(newThreadStart(AcceptMessage));thread.Start();this.Text=""+userName+"Taking";richTextBox1.Clear();richTextBox1.AppendText("System:"+userName+"连接到服务器!<-"+DateTime.Now.ToLongTimeString()+"->\r\n");btn_req.Enabled=false;btn_close.Enabled=true;btnImgFile.Enabled=true;}catch{richTextBox1.Clear();richTextBox1.AppendText("System:"+userName+"未连接上服务器!<-"+DateTime.Now.ToLongTimeString()+"->\r\n");return;}}//接收后台接收消息publicvoidAcceptMessage()//异步接收信息后台线程方法{while(true){try{if(this.socket==null||this.socket.Connected==false){richTextBox1.Clear();richTextBox1.AppendText("System:"+userName+"未连接上服务器!<-"+DateTime.Now.ToLongTimeString()+"->\r\n");break;}NetworkStreamnetStream=newNetworkStream(this.socket);//必须放在if后,this.socket可能没实例化//得到一条消息的长度byte[]dataSize=newbyte[4];//前4字节代表后面字节总数,发送时已经处理过了netStream.Read(dataSize,0,4);intsize=System.BitConverter.ToInt32(dataSize,0);//循环接收直到一条完整的消息全部读入到字节数组中byte[]message=newbyte[size];intdataleft=size;intstart=0;while(dataleft>0){intrecv=netStream.Read(message,start,dataleft);start+=recv;dataleft-=recv;}if(message[0]==101)//101代表传输图片{MemoryStreamms=newMemoryStream(message,1,message.Length-1);richTextBox1.BeginInvoke(newUpdateImg(ViewImg),newobject[]{ms});}else//默认进行普通传输{stringMsg=System.Text.Encoding.Unicode.GetString(message,1,message.Length-1);richTextBox1.BeginInvoke(newUpdateMessage(ViewMessage),newobject[]{Msg});}Thread.Sleep(100);}catch(System.Net.Sockets.SocketExceptionex){MessageBox.Show(userName+":"+ex.Message);}}}//传输文件privatevoidViewMessage(stringmsg){richTextBox1.SelectionColor=Color.SteelBlue;richTextBox1.AppendText(msg+"\n");richTextBox1.SelectionStart=richTextBox1.Text.Length;//定位到最后,保持最新消息可见richTextBox1.Focus();txt2_send.Focus();}//接收图片信息privatevoidViewImg(Streams){richTextBox1.SelectionStart=richTextBox1.Text.Length;richTextBox1.SelectionColor=Color.SteelBlue;richTextBox1.AppendText(userName+"接收图片<-"+DateTime.Now.ToLongTimeString()+"->:\r\n");Clipboard.SetDataObject(Image.FromStream(s));//利用剪切板richTextBox1.Paste();richTextBox1.SelectionColor=Color.SteelBlue;richTextBox1.AppendText("\n");richTextBox1.SelectionStart=richTextBox1.Text.Length;richTextBox1.Focus();txt2_send.Focus();}//点击发送按钮privatevoidbtn_send_Click(objectsender,EventArgse){if(txt2_send.Text==""){MessageBox.Show("请先输入内容!");txt2_send.Clear();txt2_send.Focus();return;}if(imgflag==1)//imgflag的值在方法btnImgFile_Click中可能改变{//当传输图片时byte[]imgSize=newbyte[4];//将32位整数值转换为字节数组imgSize=System.BitConverter.GetBytes(img.Length+1);//后面一个标识数:101try{NetworkStreamnetStream=newNetworkStream(this.socket);netStream.Write(imgSize,0,4);netStream.WriteByte(101);//标识数netStream.Write(img,0,img.Length);netStream.Flush();this.richTextBox1.SelectionColor=Color.LightCoral;this.richTextBox1.AppendText(userName+"<-"+DateTime.Now.ToLongTimeString()+"->:\r\n");this.richTextBox1.SelectionStart=this.richTextBox1.Text.Length;Clipboard.SetDataObject(Image.FromStream(fstream));richTextBox1.Paste();richTextBox1.SelectionColor=Color.LightCoral;this.richTextBox1.AppendText("\n");fstream.Flush();fstream.Close();//此流必须在这里才可以消除txt2_send.Paste();this.richTextBox1.SelectionStart=this.richTextBox1.Text.Length;this.richTextBox1.Focus();this.txt2_send.Text="";this.txt2_send.Focus();imgflag=0;//复原return;//不执行后面的传输文本信息}catch(System.Exceptionex){MessageBox.Show("服务器:"+ex.Message);}}//发送文本信息时this.richTextBox1.SelectionColor=Color.LightCoral;stringstr=userName+"<-"+DateTime.Now.ToLongTimeString()+"->:\r\n"+txt2_send.Text;inti=str.Length;if(i==0){return;}else{//因为str为Unicode编码,每个字符占2个字节,所以实际字节数应为字符个数*2i*=2;}byte[]dataSize=newbyte[4];//将32位整数值转换为字节数组dataSize=System.BitConverter.GetBytes(i+1);//后面一个标识数:1byte[]sendbytes=System.Text.Encoding.Unicode.GetBytes(str);try{NetworkStreamnetStream=newNetworkStream(this.socket);netStream.Write(dataSize,0,4);netStream.WriteByte(1);//标识数netStream.Write(sendbytes,0,sendbytes.Length);netStream.Flush();richTextBox1.SelectionColor=Color.LightCoral;this.richTextBox1.AppendText(str+"\n");
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度房屋买卖合同土地使用权变更范本3篇
- 2025版航空货运客户满意度提升合同3篇
- 2025年度电子商务平台销售合同重要性分析
- 二零二五年度应急预案制定与演练合同3篇
- 课程设计论文选题思路
- 二零二五年度数据中心机房监控系统隔音降噪施工合同
- 自动专业 课程设计
- 二零二五年度教育机构劳动合同规范标准3篇
- 线上艺术创作课程设计
- 瑜伽小班课程设计图
- 新人教版一年级数学下册全册导学案
- 2025年中考语文复习之现代文阅读:非连续性文本阅读(10题)
- GB/T 9755-2024合成树脂乳液墙面涂料
- 商业咨询报告范文模板
- 2024年度软件定制开发合同(ERP系统)3篇
- 家族族谱模板
- 家谱修编倡议书范文
- 高中体育与健康人教版全一册 形意强身功 课件
- 高中语文《劝学》课件三套
- 人教版一年级数学上册-教材分析
- 【企业盈利能力探析的国内外文献综述2400字】
评论
0/150
提交评论