




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
47/53华南农业大学理学院课程实验(设计)报告专业年级:11信息与计算科学学生学号:201130760学生学号:201130760学生姓名:学生姓名:实验题目:Socket应用程序设计指导老师:实验时刻:2013年11月1日-2013年11月29日目录TOC\o"1-4"\h\u240181实验内容和要求 1225121.1实验内容 1265501.2实验要求 1218761.3实验实现的功能 1119552实验过程 237122.1系统需求分析 2296162.1.1客户端
283922.1.2服务器 210802.2系统的概要设计 3224502.3具体实现 4271522.3.1客户端 4148482.3.1.1登陆功能 4278422.3.1.2谈天功能 614662.3.1.3离线谈天功能 872472.3.1.4同意离线信息功能 952562.3.1.5谈天记录功能 1057962.3.1.6显示用户状态功能 12132862.3.1.7文件传输功能 1314192.3.2服务器 1960942.3.2.1登录、注册验证功能 192882.3.2.2群聊功能 219692.3.2.3用户信息治理功能 2189943实验结果 23259984讨论与总结 24147395参考文献 24137206小组分工 251实验内容和要求1.1实验内容在学习完TCP/IP协议组后,要求掌握基于此协议实现网络通信,理解TCP与UDP的不同特征以及实现方式。基于Windows平台建立一个基于TCP/IP协议的网络通讯小应用,实验可采纳UDP或TCP实现。1.2实验要求(1)能够进行用户治理,所有用户必须登录到服务器,有服务器维护在线信息;(2)IM功能:用户登录后能够进行实时多方点到点短信息通信,如谈天;(3)能够选择要求服务器进行转发服务;(4)能够保存通信记录到数据库(SQLServer或者其他桌面型数据库或数据文件);(5)能进行双方文件传输,能够显示进度;*(6)支持断点重传,检查时需有功能随时中断传送,并在下次启动时能显示重传状态;*(7)数据包加密;*(8)实时语音双向传送功能;*(9)多方通话功能;(10)界面设计要求布局合理,信息清晰。(11)自加功能。(*为选做内容)1.3实验实现的功能(1)服务器能够进行用户治理,所有用户必须登录到服务器,有服务器维护在线信息;(2)IM功能:用户登录后能够进行实时多方点到点短信息通信,如谈天;(3)服务器离线转发功能;(4)客户端保存群谈天记录;(5)能进行双方文件传输,能够显示进度;(10)界面设计要求布局合理,信息清晰。2实验过程2.1系统需求分析2.1.1客户端
(1)登陆功能:在用户填写相关的账户和密码时,客户端能够发送连接客户端要求,当,连上客户端的时候,客户端能够将账号和密码信息发送到服务器进行核对,并返回信心(2)谈天功能:在客户端中,用户有权选择群聊依旧与某在线用户私聊
(3)离线谈天功能:在线的用户可能通过服务器将信息发给离线的用户(4)同意离线信息共能:当用户上线时,接收其他用户的离线信息(5)谈天记录功能:客户端能自动将群聊的信息保存在相应的数据库当中(6)显示用户状态功能:关于在线的用户和离线的用户能够及时显示在表格当中2.1.2服务器(1)维护用户功能:添加新用户,修改用户密码,删除用户(2)更新用户状态功能:通知客户端更新成员状态和相应的列表(3)离线功能:为离线用户保存离线信息,同时在用户上线的时发送相应的离线信息(4)检验用户信息功能:验证用户的账号和密码的正确性,并禁止用户异地同时登陆(5)显示群聊记录:在服务器中几时显示群聊的信息2.2系统的概要设计图2.1软件功能模块图图2.2服务器与客户端功能的设计图2.3服务器与客户端数据流程图2.3具体实现2.3.1客户端2.3.1.1登陆功能图2.4登陆界面(1)在按下登陆按钮的时候,程序猎取界面中的服务器中IP地址和端口号,同时检验账号和密码是否有误。若账号和密码填写上没有错误,进行连接服务器。代码如下:PrivateSubCommand1_Click()'点击登陆按钮Form2.login=False'设置能否登陆标志为“不能”IfForm1.Username.Text=""OrForm1.Usercode.Text=""Then'检查账号和密码填写是否有空MsgBox"请输入账号和密码"ElseCalltcpClient_Connect'连接服务器DoEventsIfForm2.tcpClient.State=7Then'若连接上服务器则发送账号和密码Form2.tcpClient.SendData"|"&"***"&Form1.Username.Text&"***"&"###"&Form1.Usercode.Text&"###"&"|"'***账号***###密码###DoEventsElseMsgBox"没有服务器"EndIfTimer1.Enabled=TrueEndIfEndSubPublicSubtcpClient_Connect()IfForm2.tcpClient.State<>7ThenForm2.tcpClient.CloseForm2.tcpClient.RemoteHost=Form1.txtHost.TextForm2.tcpClient.RemotePort=Form1.txtPort.TextForm2.tcpClient.ConnectDoEventsEndIfEndSub(2)当连接成功后,发送账号和密码,用相关的差不多定义好协议进行封装发送给服务器。协议是***账号***###密码###代码如下:IfForm2.tcpClient.State=7Then'若连接上服务器则发送账号和密码Form2.tcpClient.SendData"|"&"***"&Form1.Username.Text&"***"&"###"&Form1.Usercode.Text&"###"&"|"'***账号***###密码###(3)当客户端收到的服务器的协议信息是密码和账号是正确的时候才能进行真正的登录。协议是:当收到*#时,代表登录成功。当收到*ERROR时,代表没有这账号。当收到#ERROR时,代表密码错误。当收到*ONLINE时,代表账号差不多登录。代码如下:IfInStr(sData,"*#")<>0Thenlogin=TrueElseIfInStr(sData,"*ERROR")<>0ThenMsgBox"没有这账号"ElseIfInStr(sData,"#ERROR")<>0ThenMsgBox"密码错误"ElseIfInStr(sData,"*ONLINE")<>0ThenMsgBox"账号差不多登录"EndIf2.3.1.2谈天功能(1)群谈天。在图2.2的文本框中输入字符,便能够发送信息。发送的协议:$$$群谈天信息$$$,通过进行过协议封装的谈天信息,能够让服务器进行识不,不且转发给在线用户。图2.5谈天窗口PrivateSubcmdSend_Click()IftxtOut.Text=""ThenMsgBox"发送内容不能为空"ExitSubEndIftcpClient.SendData"$$$"+Form1.Username.Text+":"&txtOut.Text+"$$$"'============================================插入谈天记录a=CStr(Now())+Chr(10)+Form1.Username.Text+":"+txtOut.Text+Chr(10)Setrs=cn.Execute("insertintodata(tcp_data)values('"&a&"')")'tcp_data是表的列名'============================================插入谈天记录rtbIn.Text=rtbIn.Text&Chr(10)+CStr(Now())+Chr(10)+Form1.Username.Text+":"+txtOut.Text+Chr(10)txtOut.Text=""rtbIn.SelStart=Len(rtbIn.Text)EndSub(2)发送私聊信息。在listviews中点击相应的用户名字就能够进行私聊,在登陆的时候差不多设置好TCP控件的端口号。代码如下:PublicSubset_privatechat()Fori=1ToForm2.ListView1.ListItems.CountPrivate_Chat(i).ClientSer.ClosePrivate_Chat(i).ClientSer.LocalPort=8080+iPrivate_Chat(i).ClientSer.ListenNextEndSub(3)接收在线私聊信息。PrivateSubClientCli_DataArrival(ByValbytesTotalAsLong)ClientCli.GetDatastr,vbStringText1.Text=Text1.Text&strText1.SelStart=Len(Text1.Text)'IfMe.WindowState=1Then'Timer2.Enabled=True'EndIfEndSubPrivateSubClientSer_DataArrival(ByValbytesTotalAsLong)ClientSer.GetDatastr,vbStringText1.Text=Text1.Text&strText1.SelStart=Len(Text1.Text)'IfMe.WindowState=1Then'Timer2.Enabled=True'EndIfEndSub2.3.1.3离线谈天功能在输入框中输入私聊信息时,先推断是否在线,假如是在线的话直接利用差不多和对方连接的TCP控件进行发送信息。假如是离线用户的话,利用协议将封装好的离线信息发送给服务器,在通过服务器发送给离线的用户。离线信息协议:%**1发送者账号**1**2接收者账号**2**$$离线的信息**$$%代码如下:PrivateSubCommand1_Click()DimstrAsStringIfLen(Text2.Text)=0ThenMsgBox("发送内容不能为空!")ExitSubEndIfstr=Form1.Username.Text&""&Time&Chr(13)&Chr(10)&Text2.Textstr=str&Chr(13)&Chr(10)&Chr(13)&Chr(10)IfClientSer.State=7ThenClientSer.SendDatastr'MsgBox"已连接上对方"ElseIfClientCli.State=7ThenClientCli.SendDatastrEndIfIfClientCli.State<>7AndClientSer.State<>7Then'离线信息设置Form2.tcpClient.SendData"%"+"**1"+Label2.Caption+"**1"+"**2"+Label3.Caption+"**2"+"**$$"+str+"**$$"+"%"DoEventsEndIfText1.Text=Text1.Text&strText1.SelStart=Len(Text1.Text)Text2.Text=""EndSub图2.6私聊对话框2.3.1.4同意离线信息功能接收离线私聊信息。当收到服务器的离线信息时,对发送过来的字符串进行信息提取,提取动身送者、接收者和信息。Functioncheck_outlinemessage(messageAsString)sender_where1=0reciever_where1=0outmessage_where1=0sender_where2=0reciever_where2=0outmessage_where2=0IfInStr(message,"**2")<>0ThenDosender_where1=InStr(sender_where2+1,message,"**1")sender_where2=InStr(sender_where1+1,message,"**1")sender=Mid(message,sender_where1+3,sender_where2-sender_where1-3)outmessage_where1=InStr(outmessage_where2+1,message,"**$$")outmessage_where2=InStr(outmessage_where1+1,message,"**$$")outmessage=Mid(message,outmessage_where1+4,outmessage_where2-outmessage_where1-4)Forn=1ToForm2.ListView1.ListItems.CountIfForm2.ListView1.ListItems(n).Text=senderThenPrivate_Chat(n).Text1.Text=Private_Chat(n).Text1.Text&outmessagePrivate_Chat(n).Text1.SelStart=Len(Private_Chat(n).Text1.Text)Form2.ListView1.ListItems(n).ForeColor=vbRedForm2.ListView1.ListItems(n).ListSubItems.Item(1).ForeColor=vbRedForm2.ListView1.ListItems(n).ListSubItems.Item(2).ForeColor=vbRedEndIfNextLoopUntilInStr(sender_where2+1,message,"**1")=0EndIfEndFunction2.3.1.5谈天记录功能(1)读取数据库中的谈天信息。添加VB的控件ADO,ADO控件建立起读取谈天记录的桌面型数据库access,读取数据库中信息,如图2.4。代码如下:PubliccnAsADODB.ConnectionPublicrsAsADODB.RecordsetSubadddata()Setcn=NewADODB.Connectioncn.ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;DataSource="&App.Path&"\data.mdb;PersistSecurityInfo=False"cn.OpenSetrs=cn.Execute("select*fromdata")EndSub图2.7数据库的信息当按下群谈天记录的时候弹出对应的RichTextBox控件如下图图2.8群谈天记录对话框(2)将群谈天信息加入到数据库。提取$$$与$$$之间的群谈天信息IfInStr(sData,"$$$")<>0Thengroup_chat1=InStr(sData,"$$$")group_chat2=InStr(group_chat1+1,sData,"$$$")ssData=Mid(sData,group_chat1+3,group_chat2-group_chat1-3)'============================================插入谈天记录a=CStr(Now())+Chr(10)+ssData+Chr(10)Setrs=cn.Execute("insertintodata(tcp_data)values('"&a&"')")'tcp_data是表的列名'============================================插入谈天记录rtbIn.Text=rtbIn.Text+Chr(10)+CStr(Now())+Chr(10)+ssData+Chr(10)rtbIn.SelStart=Len(rtbIn.Text)EndIfCallcheck_useronline(sData)Callset_privatechat2.3.1.6显示用户状态功能(1)当用户登录的时候,服务器会发送当前用户列表的信息给客户端,协议为***用户名***@@@IP地址@@@,当IP地址为NULL时,客户端识不为没有上线,只有不是NULL的时候才是真正有上线,关于上线的用户,在listview中的状态会由0变为1,表示差不多上线。同时会清空listview,将因此的用户进行重新的加载。如图2.6.代码如下:PublicSubcheck_useronline(gDataAsString)account_where1=0IP_where1=0account_where2=0IP_where2=0IfInStr(gData,"***")>=1ThenForm2.ListView1.ListItems.Clear'清空列表Doaccount_where1=InStr(account_where2+1,gData,"***")account_where2=InStr(account_where1+1,gData,"***")Username=Mid(gData,account_where1+3,account_where2-account_where1-3)IP_where1=InStr(IP_where2+1,gData,"@@@")IP_where2=InStr(IP_where1+1,gData,"@@@")UserIP=Mid(gData,IP_where1+3,IP_where2-IP_where1-3)Setitmx=Form2.ListView1.ListItems.Add(1,,Username)itmx.SubItems(2)=UserIPIfUserIP<>"NULL"Thenitmx.SubItems(1)=1Elseitmx.SubItems(1)=0EndIfLoopUntilInStr(account_where2+1,gData,"***")=0EndIfEndSub图2.9用户状态列表(2)当用户退出的时候,会发送Q的字符串给服务器,告诉服务器退出,同时让服务器发送用户状态信息给各个在线用户,再次刷新用户。代码如下:PrivateSubForm_QueryUnload(CancelAsInteger,UnloadModeAsInteger)tcpClient.SendData"Q"&CStr(Now())DoEventsUnloadForm3UnloadForm2Form1.ShowEndSub2.3.1.7文件传输功能基于TCP/IP协议的通信,需要分不建立客户端应用程序和服务器段应用程序,大致流程如图4-1图2.10客户端与服务器数据流图实现原理:发送方先猎取待传输文件的差不多信息,要紧是文件名及文件长度(用于创建数据缓冲区);然后,将其发送给接收方;接着,建立和文件一样大小的数据缓冲区,并将文件读入;最后,将数据缓冲区中的数据发送给接收方。与此同时,当接收方接收到文件名和文件长度之后,就为其创建新的文件和数据缓冲区;然后,接收传输的文件数据,并将其放在数据缓冲区中;最后,依次将数据缓冲区的数据写入新创建的文件中。如此便完成了不同计算机之间的文件传输。在本次实验中,于私人谈天模式里,当勾上“打开文件传输通道后”,右边button将变为可用,如下图:,图2.11文件传输现在点击“发送文件”按钮,便会弹出窗体图2.12文件传输界面这时窗体里的winsock控件(数组)将处于监听状态,执行代码如下Forj=1ToForm2.ListView1.ListItems.CountPrivate_send(j).wskServer.ClosePrivate_send(j).wskServer.LocalPort=8000+jPrivate_send(j).wskServer.ListenNextj同时若现在点击“扫瞄”时,将会调用系统里的控件“Comdlg”,执行下段代码PrivateSubCommand1_Click()WithComdlg.CancelError=TrueOnErrorGoToOpenErr.DialogTitle=“打开一个测试文件…”.Filter=“所有文件(*.*)|*.*”.Flags=&H4.ShowOpenText3.Text=.FileNameEndWithOpenErr:EndSub若现在选择的文件正确(路径,文件存在),将能够点击“发送按钮”,已连接的对方的winsock将会发生”请求”事件,同意“请求”的话,将发生“数据到达”,相关代码如下所示:PrivateSubwskServer_ConnectionRequest(ByVal equestedAsLong)IfPrivate_send(SelectNo).wskServer.State<>sckClosedThenPrivate_send(SelectNo).wskServer.ClosePrivate_send(SelectNo).wskServer.Accept equestedList1.ClearList1.AddItem“已连接…”Command2.Enabled=TrueEndSubPrivateSubwskServer_DataArrival(ByValbytesTotalAsLong)DimWskChatAsStringPrivate_send(SelectNo).wskServer.GetDataWskChatIfWskChat=“NoThanks”ThenMsgBox“对方拒收你发送的文件.”,vbExclamation,“Server”ElseIfWskChat=“OkSend”ThenMsgBox“对方同意了你的文件.”&vbCrLf&vbCrLf&“单击“确定”开始传送…”,vbInformation,“Server”GetFileNum=FreeFileLenFile=FileLen(Text3.Text)‘ProBarLen=LenFileVarPlus=0‘OpenText3.TextForBinaryAs#GetFileNumOnSend=TrueCommand2.Enabled=FalseCallTCPSendFile(Private_send(SelectNo).wskServer,GetFileNum,SplitFile)EndIfEndSub若没有连接上,我们添加了Timer控件,来监控状态,若处于“连接关闭”状态,将重置winsock,并显示相应信息给用户(例如“传送”按钮不可用等),如下图:图2.13文件传输中载入文件相关代码如下:PrivateSubTimer1_Timer()IfPrivate_send(SelectNo).wskServer.State=sckClosingThenList1.ClearList1.AddItem"对方的连接已关闭..."Private_send(SelectNo).wskServer.ClosePrivate_send(SelectNo).wskServer.LocalPort=8000+SelectNoPrivate_send(SelectNo).wskServer.ListenCommand2.Enabled=FalseEndIfEndSub依照上面所述的原理,是使用内存来存储数据,然而,当需要传送的数据比较大时,就不能像以上介绍的那样,直接将整个文件放入数据缓冲区中了,我们的内存是无法忍受用一个几百MB甚至上GB的空间去存储那些临时数据的。显然,这种做法已远不能满足我们的需求,这时能够将文件按照一定的大小,分成若干个数据包(远小于内存的容量)。首先,设置数据包的大小(如64K),依照文件的差不多信息(要紧文件的长度),计算出总共需要的数据包数;然后,依次读取同数据包一样大小的数据到数据缓冲区中;接着,将数据缓冲区中的数据,发送到指定的计算机上;同时在另一端,建立一个数据缓冲区,缓冲区的大小要依照接收到的数据来确定,依次接收客户端传输过来的数据包,并将数据缓冲区的数据写入相应的文件中,如此就专门容易实现大文件的传输了,这是一种较为常用的方法(较为容易实现断点续传),只是本次采纳的是一种“迭代递归”的思想,使用自己编写的函数SplitFile()来略微简单实现传输大文件,但断点重传功能将受到限制,相关代码如下:PrivateFunctionSplitFile()AsLongDimGetCountAsLongIfLenFile>=8192ThenGetCount=8192LenFile=LenFile-GetCountElseGetCount=LenFileLenFile=LenFile-GetCountEndIfVarPlus=VarPlus+GetCountProBar.Value=(VarPlus/ProBarLen)*100SplitFile=GetCountEndFunctionPrivateSubTCPSendFile(objWinSockAsWinsock,FileNumberAsInteger,SendLenAsLong)DimFileByte()AsByte,iAsLongReDimFileByte(SendLen-1)Get#FileNumber,,FileByteobjWinSock.SendDataFileByteEndSub至于显示进度,在私聊和传送文件窗体里,我们添加了VB自带的控件progressbar,进度也依照以传送文件的大小和总大小作简单除法:ProBar.Value=(VarPlus/ProBarLen)*100来显示,图示效果如下:图2.14文件传输接收完毕图2.15文件传输发送完毕2.3.2服务器2.3.2.1登录、注册验证功能双击服务器.exe,进入初始界面,那个地点winsock将初始化,得到IP地址同时设置端口等,并对客户端治理界面进行初始化(现在该界面不显示但却已执行相关操作,点击“客户端”界面时显现):图2.16服务器界面图2.17客户端治理界面当有客户端请求连接服务器时,同意的话,发生”事件到达”,服务器采取机制:推断数据种类,并采取相关操作。代码如下:DimsDataAsStringDimsNameAsStringtcpServer(Index).GetDatasDatartbSave.SelStart=Len(rtbSave.Text)'客户端向服务器发送差不多登录和退出信息'===========================================================sName=Left(sData,1)IfsName="C"ThentcpServer(Index).SendData"C_OK"DoEventsElseIfsName="Q"ThentcpServer(Index).SendData"Q_OK."DoEventsCalldel_IP(tcpServer(Index).RemoteHostIP)'在客服端治理中删除已退出客户端的IP地址和上线记录tcpServer(Index).CloseNumOnline=NumOnline-1EndIf'==========================================================='客户端向服务器发送账号和密码,服务器提取账号和密码'===========================================================IfInStr(sData,"|")Thenaccount_where1=InStr(sData,"***")account_where2=InStr(account_where1+1,sData,"***")user(0).uName=Mid(sData,account_where1+3,account_where2-account_where1-3)'***用户名***password_where1=InStr(sData,"###")password_where2=InStr(password_where1+1,sData,"###")user(0).uPWD=Mid(sData,password_where1+3,password_where2-password_where1-3)'###密码***Callcheck_account_pwd(Trim(user(0).uName),Trim(user(0).uPWD),Index)'校对数据库中的密码和账号是否符合EndIf'===========================================================2.3.2.2群聊功能因为winsock“数据到达”处理,他需要推断到达的是“登陆和退出信息”依旧“已登陆用户间的群谈天记录”,那个地点我们做了个简单的协议“InStr(sData,"$$$")”,相关代码如下:IfInStr(sData,"$$$")<>0ThenForn=1ToNumIftcpServer(n).State=7Andn<>IndexThentcpServer(n).SendDatasDataDoEventsEndIfNextgroup_chat1=InStr(sData,"$$$")group_chat2=InStr(group_chat1+1,sData,"$$$")sData=Mid(sData,group_chat1+3,group_chat2-group_chat1-3)rtbSave.SelStart=Len(rtbSave.Text)rtbSave.Text=rtbSave.Text+Chr(10)+CStr(Now())+Chr(10)+sData+Chr(10)rtbSave.SelStart=Len(rtbSave.Text)EndIf2.3.2.3用户信息治理功能那个地点我们采纳单选按钮(添加和修改)来实现客户端治理和维护,选择注册或者删除,点击“确定后”将显示相应功能,相关代码如下:PrivateSubcommand1_Click()Dimi,j,kAsIntegerIfLen(Text1.Text)=0Thenk=MsgBox("账户不能为空!",64,"提示")ExitSubEndIfIfOption1.Value=TrueThenFori=1ToListView1.ListItems.CountIfListView1.ListItems(i).Text=Text1.TextThenk=MsgBox("此账户差不多存在,不能添加!",64,"提示")ExitSubEndIfNextiSetitmx=ListView1.ListItems.Add(1,,Text1.Text)itmx.SubItems(1)=Text2.Textitmx.SubItems(2)=0ListView_Change1=ListView_Change1+1CallData_Add(Text1.Text,Text2.Text)CallCon_Closek=MsgBox("差不多添加成功!",64,"提示")Elsej=ListView1.SelectedItem.IndexForm2.ListView1.ListItems(j).SubItems(1)=Text2.TextForm2.ListView1.ListItems(j).SubItems(2)="0"Form2.ListView1.ListItems(j).SubItems(3)=""ListView_Change1=ListView_Change1+1CallData_Mod(Text1.Text,Text2.Text)CallCon_Closek=MsgBox("修改成功!",64,"提示")Text3.Text="0"EndIfLabel7.Caption=ListView1.ListItem
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论