计算机网络课程设计---基于TCP的点对点即时通信工具姓名:杨祺鹏班级:191072学号:20071000566指导老师:梁庆中一.设计题目及设计目标1.设计题目题目:实现一个基于网络的应用要求:利用TCP或UDP完成联网通信,并在此基础上完成数据应用。2.设计目标这个软件实现的功能主要包括局域网内的点对点聊天(基本功能),局域网内搜索IP并显示,搜索任意IP段并显示。应用的主要范围面向局域网。二.设计的思路1.选用语言:C#2.使用的主要技术:TcpClient,thread(线程)3.功能结构图。三.设计的实现程序启动(客户)另一个线程启动(服务器)监听端口获取本机IP搜索指定IP段向指定IP发送消息修改主进程控件程序流程图:连接不成功不为空为空连接成功继续聊天程序结束搜索指定段IP,或者搜索本地局域网IP连接IP程序初始化服务器线程启动对指定端口进行监听监听IP传输数据是否为空修改主进程控件关闭连接,关闭数据流发送数据关闭连接,关闭数据流用户选择程序结束1.获取本机IP模块使用的C#的IPHOSTENTRY和IPADDRESS两个类stringhostname1=Dns.GetHostName();IPHostEntrymyentry=Dns.GetHostByName(hostname1);IPAddressmyaddress=newIPAddress(myentry.AddressList[0].Address);stringmyip=myaddress.ToString();this.localip.Text=myip;用已经获取的本机的名字来获取本机的IP。2.获取局域网IPintipdot=myip.LastIndexOf('.');myip=myip.Substring(0,ipdot+1);stringaa=0;//获取本机的IP后,获取最后一个.的位置,并且将这个.后面的数据替换成0和255,实现从局域网0-255的搜索stringbb=255;stringstartip=myip+aa;stringendip=myip+bb;this.ipstart.Text=startip;this.ipend.Text=endip;3.搜索指定IP段的IP地址对输入的IP段进行搜索,stringipcur=this.ipstart.Text;intipdot=ipcur.LastIndexOf('.');stringippre=ipcur.Substring(0,ipdot+1);for(inti=0;i=3;i++){MessageBox.Show(开始搜索);stringscanip=ippre+i.ToString();IPAddressmyscanip=IPAddress.Parse(scanip);IPHostEntrymyscanhost=null;try{myscanhost=Dns.GetHostByAddress(myscanip);}catch{continue;获取输入IP的最后一个点的位置,并且先设置一个变量为要添加到这个点后面的数据。在这里定义搜索多少次,因为搜索很慢,所以暂时只搜索3次就停下了要搜索的IP是搜索框内的IP去尾得到的,在这里添加上IP的尾端进行搜索。判断是否可以搜索此IP}if(myscanhost.HostName!=null){MessageBox.Show(搜索到一个结果);this.ipbox.Items.Add(可用IP:);this.ipbox.Items.Add(scanip);this.ipbox.Items.Add(此IP的主机名:);this.ipbox.Items.Add(myscanhost.HostName);}运行截图:4.在程序启动时同时启动另一个线程作为服务器C/S模式都有服务器和客户端之分,在这个程序中服务器端被简化了,服务器程序不具有主动的功能,只能对端口进行监听并且修改主进程的控件。privatevoidForm1_Load(objectsender,EventArgse){Control.CheckForIllegalCrossThreadCalls=false;Threadserver=newThread(newThreadStart(serverfuntion));server.IsBackground=true;如果可以通过IP搜索到该ip的名字,则进行添加。在主进程LOAD的时候就启动另外一个服务器线程server.Start();}privatevoidserverfuntion(){DateTimedt=newDateTime();dt=DateTime.Now;if(this.scanedip.Text!=null){TcpListenermylis=newTcpListener(IPAddress.Any,51888);mylis.Start();while(true){TcpClientmytcp=newTcpClient();mytcp=mylis.AcceptTcpClient();//MessageBox.Show(连接建立成功!);NetworkStreammystream=mytcp.GetStream();StreamReadersr=newStreamReader(mystream);//MessageBox.Show(流建立成功!);stringreceived=;received=sr.ReadToEnd();//MessageBox.Show(消息接受成功!);if(received!=null){this.messagegeted.Items.Add(dt);this.messagegeted.Items.Add(received);}//MessageBox.Show(文本框修改成功!);sr.Close();mystream.Close();mytcp.Close();//MessageBox.Show(流关闭,连接关闭!);}}5.连接指定IP地址,并且进行数据传输连接指定IPprivatevoidbutton2_Click(objectsender,EventArgse){IPAddressmyip=IPAddress.Parse(this.localip.Text.ToString());IPAddresstoip=IPAddress.Parse(this.scanedip.Text.ToString());TcpClientmytcp=newTcpClient();try{mytcp.Connect(toip,51888);}catch(SocketException){获取当前时间以显示连接成功的时间对任意IP的指定端口进行监听,无限循环的。对之前的tcplinstener进行定义,定义为接受的连接。获取接受的连接的数据流。获取数据流数据。连接服务端也会产生连接数据流,只有当数据流的数据不为空的时候,才对主进程的控件进行修改。关闭数据流,关闭连接。连接指向IP的51888端口,连接不成功会显示不成功。MessageBox.Show(该IP不存在!);}this.connectinfo.Items.Add(正在连接IP:);this.connectinfo.Items.Add(toip);if(mytcp.Connected==true){this.connectinfo.Items.Add(连接成功!);this.send.Enabled=true;mytcp.Close();}else{this.connectinfo.Items.Add(连接失败!);this.send.Enabled=false;}}运行截图:数据传输privatevoidsend_Click(objectsender,EventArgse){DateTimedt=newDateTime();dt=DateTime.Now;IPAddressmyip=IPAddress.Parse(this.localip.Text.ToString());IPAddresstoip=IPAddress.Parse(this.scanedip.Text.ToString());连接成功后对txtbox进行数据添加,并且将发送信息键置成可使用的。因为发送信息键是在连接成功后才可用的,因此不存在连接失败的可能。TcpClientmytcp=newTcpClient();mytcp.Connect(toip,51888);//MessageBox.Show(连接建立!);NetworkStreammystream=mytcp.GetStream();//数据流建立stringmessage1=this.sendmessage.Text;stringmessage2=this.localip.Text;stringmessage3=message1+本条消息来自于:+message2;stringmessage4=你悄悄的对+this.scanedip.Text+说:+message1;this.messagegeted.Items.Add(dt);this.messagegeted.Items.Add(message4);byte[]sendmessage1=System.Text.Encoding.UTF8.GetBytes(message3);mystream.Write(sendmessage1,0,sendmessage1.Length);mystream.Close();//关闭数据流mytcp.Close();//关闭连接this.sendmessage.Clear();//MessageBox.Show(消息发送成功!);}运行截图:四.课程设计过程总结1.程序总结程序实现的功能比较简单,只有搜索IP和点对点聊天,其中搜索IP速度很慢,大概要用3秒左右才能搜索一个IP,暂时还没有解因为tcpclient不能获取连接的时间和ip,所以在发送的时候把本地ip和名字,连接IP都发送出去。关闭数据流,关闭连接。发送数据要用特殊格式。决这个问题,总体上达到了课程设计的目标,要求的功能基本都实现了。在后续的功能增强中,会逐步添加群聊还有添加好友的功能,登录界面也要用数据库进行管理,依靠每个人的数据库数据有不同的登录界面和好友。2.遇到的问题和解决过程遇到的问题主要是两个,一个是C/S模式都是要一个客户端一个服务端,如何让他们在一个程序中实现;一个是对TCPCLIENT的使用不太熟悉,之前没有用到过。对于TCPCLIENT的学习是自己找资料还有在网上看实例学会的,当时和SOCKET有点弄混了,所以在刚开始的时候出了点小问题,随着对tcpclient的理解的加深问题就解决了。另外一个问题是用线程来解决的,这个方法是参考了网上的高手给的办法,但是用线程是不能更改主线程的控件的,还要加上一句类似声明的代码,这一句代码看似简单,实际上我找到代码并且测试成功用了将近一个小时的时间。在发现问题,解决问题的过程中,我的知识储备也是愈加的丰富,在和同学们的交流中也学习到了很多知识和很多很好的想法。在这里对191072班的刘锦权同学提出特别感谢,他教给我线程和事件的使用方法。3.课程设计感想通过几天紧张有序的忙碌,网络课程设计程序终于出炉了。基于我们之前对TCP的学习和理解,加上在自己买的资料中进行学习,在程序中应用TCP连接还是不太难的。TCP强大的功能和使之实现的简洁的代码给我留下了很深刻的印象,在以后的学习生活中还要进一步进行学习。这一次网络课程设计深化了我对TCP的理解,也对经常要使用的C/S模式有了一定的了解,锻炼了C++的编程动手能力,有很强的成就感。TCP作为连接控件应用非常广泛,前景非常好,我会以这次课程设计为契机,进一步对TCP知识进行学习和发掘。对我而言,知识上的收获重要,精神上的丰收更加可喜。让我知道了学无