華南農(nóng)業(yè)大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告_第1頁
華南農(nóng)業(yè)大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告_第2頁
華南農(nóng)業(yè)大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告_第3頁
華南農(nóng)業(yè)大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告_第4頁
華南農(nóng)業(yè)大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)報(bào)告_第5頁
已閱讀5頁,還剩26頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、華南農(nóng)業(yè)大學(xué)理學(xué)院課程實(shí)驗(yàn)(設(shè)計(jì))報(bào)告專業(yè)年級(jí): 11信息與計(jì)算科學(xué) 學(xué)生學(xué)號(hào): 201130760 學(xué)生學(xué)號(hào): 201130760 學(xué)生姓名: 學(xué)生姓名: 實(shí)驗(yàn)題目: Socket應(yīng)用程序設(shè)計(jì) 指導(dǎo)老師: 實(shí)驗(yàn)時(shí)間:2013年11月1日-2013年11月29日目 錄1實(shí)驗(yàn)內(nèi)容和要求11.1實(shí)驗(yàn)內(nèi)容11.2實(shí)驗(yàn)要求11.3實(shí)驗(yàn)實(shí)現(xiàn)的功能12實(shí)驗(yàn)過程22.1系統(tǒng)需求分析22.1.1客戶端 22.1.2服務(wù)器22.2系統(tǒng)的概要設(shè)計(jì)32.3具體實(shí)現(xiàn)42.3.1客戶端42.3.1.1登陸功能42.3.1.2聊天功能62.3.1.3離線聊天功能82.3.1.4接受離線信息功能92.3.1.5聊

2、天記錄功能102.3.1.6顯示用戶狀態(tài)功能122.3.1.7文件傳輸功能132.3.2服務(wù)器192.3.2.1登錄、注冊驗(yàn)證功能192.3.2.2群聊功能212.3.2.3用戶信息管理功能213實(shí)驗(yàn)結(jié)果234討論與總結(jié)245參考文獻(xiàn)246小組分工251實(shí)驗(yàn)內(nèi)容和要求1.1實(shí)驗(yàn)內(nèi)容在學(xué)習(xí)完TCP/IP協(xié)議組后,要求掌握基于此協(xié)議實(shí)現(xiàn)網(wǎng)絡(luò)通信,理解TCP與UDP的不同特征以及實(shí)現(xiàn)方式?;赪indows平臺(tái)建立一個(gè)基于TCP/IP協(xié)議的網(wǎng)絡(luò)通訊小應(yīng)用,實(shí)驗(yàn)可采用UDP或TCP實(shí)現(xiàn)。1.2實(shí)驗(yàn)要求(1)能夠進(jìn)行用戶管理,所有用戶必須登錄到服務(wù)器,有服務(wù)器維護(hù)在線信息;(2)IM功能:用戶登錄后能夠

3、進(jìn)行實(shí)時(shí)多方點(diǎn)到點(diǎn)短信息通信,如聊天;(3)能夠選擇要求服務(wù)器進(jìn)行轉(zhuǎn)發(fā)服務(wù);(4)能夠保存通信記錄到數(shù)據(jù)庫(SQL Server或者其他桌面型數(shù)據(jù)庫或數(shù)據(jù)文件);(5)能進(jìn)行雙方文件傳輸,能夠顯示進(jìn)度;*(6)支持?jǐn)帱c(diǎn)重傳,檢查時(shí)需有功能隨時(shí)中斷傳送,并在下次啟動(dòng)時(shí)能顯示重傳狀態(tài);*(7)數(shù)據(jù)包加密;*(8)實(shí)時(shí)語音雙向傳送功能;*(9)多方通話功能;(10)界面設(shè)計(jì)要求布局合理,信息清晰。(11)自加功能。(*為選做內(nèi)容)1.3實(shí)驗(yàn)實(shí)現(xiàn)的功能(1)服務(wù)器能夠進(jìn)行用戶管理,所有用戶必須登錄到服務(wù)器,有服務(wù)器維護(hù)在線信息;(2)IM功能:用戶登錄后能夠進(jìn)行實(shí)時(shí)多方點(diǎn)到點(diǎn)短信息通信,如聊天;(3)

4、服務(wù)器離線轉(zhuǎn)發(fā)功能;(4)客戶端保存群聊天記錄;(5)能進(jìn)行雙方文件傳輸,能夠顯示進(jìn)度;(10)界面設(shè)計(jì)要求布局合理,信息清晰。2實(shí)驗(yàn)過程2.1系統(tǒng)需求分析2.1.1客戶端  (1)登陸功能:在用戶填寫相關(guān)的賬戶和密碼時(shí),客戶端能夠發(fā)送連接客戶端要求,當(dāng),連上客戶端的時(shí)候,客戶端能夠?qū)①~號(hào)和密碼信息發(fā)送到服務(wù)器進(jìn)行核對,并返回信心(2)聊天功能:在客戶端中,用戶有權(quán)選擇群聊還是與某在線用戶私聊 (3)離線聊天功能:在線的用戶可能通過服務(wù)器將信息發(fā)給離線的用戶(4)接受離線信息共能:當(dāng)用戶上線時(shí),接收其他用戶的離線信息(5)聊天記錄功能:客戶端能自動(dòng)將群聊的信息保存

5、在相應(yīng)的數(shù)據(jù)庫當(dāng)中(6)顯示用戶狀態(tài)功能:對于在線的用戶和離線的用戶能夠及時(shí)顯示在表格當(dāng)中2.1.2服務(wù)器(1)維護(hù)用戶功能:添加新用戶,修改用戶密碼,刪除用戶(2)更新用戶狀態(tài)功能:通知客戶端更新成員狀態(tài)和相應(yīng)的列表(3)離線功能:為離線用戶保存離線信息,并且在用戶上線的時(shí)發(fā)送相應(yīng)的離線信息(4)檢驗(yàn)用戶信息功能:驗(yàn)證用戶的賬號(hào)和密碼的正確性,并禁止用戶異地同時(shí)登陸(5)顯示群聊記錄:在服務(wù)器中幾時(shí)顯示群聊的信息2.2系統(tǒng)的概要設(shè)計(jì)圖2.1軟件功能模塊圖圖2.2服務(wù)器與客戶端功能的設(shè)計(jì)圖2.3服務(wù)器與客戶端數(shù)據(jù)流程圖2.3具體實(shí)現(xiàn)2.3.1客戶端2.3.1.1登陸功能圖2.4登陸界面(1)在

6、按下登陸按鈕的時(shí)候,程序獲取界面中的服務(wù)器中IP地址和端口號(hào),同時(shí)檢驗(yàn)賬號(hào)和密碼是否有誤。若賬號(hào)和密碼填寫上沒有錯(cuò)誤,進(jìn)行連接服務(wù)器。代碼如下:Private Sub Command1_Click() '點(diǎn)擊登陸按鈕 Form2.login = False '設(shè)置能否登陸標(biāo)志為“不能” If Form1.Username.Text = "" Or Form1.Usercode.Text = "" Then '檢查賬號(hào)和密碼填寫是否有空 MsgBox "請輸入賬號(hào)和密碼" Else Call tcpClient_

7、Connect '連接服務(wù)器 DoEvents If Form2.tcpClient.State = 7 Then '若連接上服務(wù)器則發(fā)送賬號(hào)和密碼 Form2.tcpClient.SendData "|" & "*" & Form1.Username.Text & "*" & "#" & Form1.Usercode.Text & "#" & "|" '*賬號(hào)*#密碼# DoEvents Els

8、e MsgBox "沒有服務(wù)器" End If Timer1.Enabled = True End IfEnd SubPublic Sub tcpClient_Connect() If Form2.tcpClient.State <> 7 Then Form2.tcpClient.Close Form2.tcpClient.RemoteHost = Form1.txtHost.Text Form2.tcpClient.RemotePort = Form1.txtPort.Text Form2.tcpClient.Connect DoEvents End IfEn

9、d Sub(2)當(dāng)連接成功后,發(fā)送賬號(hào)和密碼,用相關(guān)的已經(jīng)定義好協(xié)議進(jìn)行封裝發(fā)送給服務(wù)器。協(xié)議是*賬號(hào)*#密碼#代碼如下:If Form2.tcpClient.State = 7 Then '若連接上服務(wù)器則發(fā)送賬號(hào)和密碼 Form2.tcpClient.SendData "|" & "*" & Form1.Username.Text & "*" & "#" & Form1.Usercode.Text & "#" & "|

10、" '*賬號(hào)*#密碼#(3)當(dāng)客戶端收到的服務(wù)器的協(xié)議信息是密碼和賬號(hào)是正確的時(shí)候才能進(jìn)行真正的登錄。協(xié)議是:當(dāng)收到*#時(shí),代表登錄成功。當(dāng)收到*ERROR時(shí),代表沒有這賬號(hào)。當(dāng)收到#ERROR時(shí),代表密碼錯(cuò)誤。當(dāng)收到*ONLINE時(shí),代表賬號(hào)已經(jīng)登錄。代碼如下:If InStr(sData, "*#") <> 0 Then login = True ElseIf InStr(sData, "*ERROR") <> 0 Then MsgBox "沒有這賬號(hào)" ElseIf InStr(sDat

11、a, "#ERROR") <> 0 Then MsgBox "密碼錯(cuò)誤" ElseIf InStr(sData, "*ONLINE") <> 0 Then MsgBox "賬號(hào)已經(jīng)登錄"End If2.3.1.2聊天功能(1)群聊天。在圖2.2的文本框中輸入字符,便可以發(fā)送信息。發(fā)送的協(xié)議:$群聊天信息$,通過進(jìn)行過協(xié)議封裝的聊天信息,能夠讓服務(wù)器進(jìn)行識(shí)別,別且轉(zhuǎn)發(fā)給在線用戶。圖2.5聊天窗口Private Sub cmdSend_Click() If txtOut.Text = "

12、;" Then MsgBox "發(fā)送內(nèi)容不能為空" Exit Sub End If tcpClient.SendData "$" + Form1.Username.Text + " : " & txtOut.Text + "$" '=插入聊天記錄 a = CStr(Now() + Chr(10) + Form1.Username.Text + " : " + txtOut.Text + Chr(10) Set rs = cn.Execute("insert i

13、nto data (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)End Sub(2)

14、發(fā)送私聊信息。在listviews中點(diǎn)擊相應(yīng)的用戶名字就可以進(jìn)行私聊,在登陸的時(shí)候已經(jīng)設(shè)置好TCP控件的端口號(hào)。代碼如下:Public Sub set_privatechat() For i = 1 To Form2.ListView1.ListItems.Count Private_Chat(i).ClientSer.Close Private_Chat(i).ClientSer.LocalPort = 8080 + i Private_Chat(i).ClientSer.Listen NextEnd Sub(3)接收在線私聊信息。Private Sub ClientCli_DataArri

15、val(ByVal bytesTotal As Long) ClientCli.GetData str, vbString Text1.Text = Text1.Text & str Text1.SelStart = Len(Text1.Text) 'If Me.WindowState = 1 Then 'Timer2.Enabled = True 'End IfEnd SubPrivate Sub ClientSer_DataArrival(ByVal bytesTotal As Long) ClientSer.GetData str, vbString Te

16、xt1.Text = Text1.Text & str Text1.SelStart = Len(Text1.Text) 'If Me.WindowState = 1 Then 'Timer2.Enabled = True 'End IfEnd Sub2.3.1.3離線聊天功能在輸入框中輸入私聊信息時(shí),先判斷是否在線,假如是在線的話直接利用已經(jīng)和對方連接的TCP控件進(jìn)行發(fā)送信息。假如是離線用戶的話,利用協(xié)議將封裝好的離線信息發(fā)送給服務(wù)器,在通過服務(wù)器發(fā)送給離線的用戶。離線信息協(xié)議:%*1發(fā)送者賬號(hào)*1*2接收者賬號(hào)*2*$離線的信息*$%代碼如下:Private

17、 Sub Command1_Click() Dim str As String If Len(Text2.Text) = 0 Then MsgBox ("發(fā)送內(nèi)容不能為空!") Exit Sub End If str = Form1.Username.Text & " " & Time & Chr(13) & Chr(10) & Text2.Text str = str & Chr(13) & Chr(10) & Chr(13) & Chr(10) If ClientSer.Stat

18、e = 7 Then ClientSer.SendData str 'MsgBox "已連接上對方" ElseIf ClientCli.State = 7 Then ClientCli.SendData str End If If ClientCli.State <> 7 And ClientSer.State <> 7 Then '離線信息設(shè)置 Form2.tcpClient.SendData "%" + "*1" + Label2.Caption + "*1" + &qu

19、ot;*2" + Label3.Caption + "*2" + "*$" + str + "*$" + "%" DoEvents End If Text1.Text = Text1.Text & str Text1.SelStart = Len(Text1.Text) Text2.Text = ""End Sub圖2.6私聊對話框2.3.1.4接受離線信息功能接收離線私聊信息。當(dāng)收到服務(wù)器的離線信息時(shí),對發(fā)送過來的字符串進(jìn)行信息提取,提取出發(fā)送者、接收者和信息。Functio

20、n check_outlinemessage(message As String) sender_where1 = 0 reciever_where1 = 0 outmessage_where1 = 0 sender_where2 = 0 reciever_where2 = 0 outmessage_where2 = 0 If InStr(message, "*2") <> 0 Then Do sender_where1 = InStr(sender_where2 + 1, message, "*1") sender_where2 = InS

21、tr(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, out

22、message_where1 + 4, outmessage_where2 - outmessage_where1 - 4) For n = 1 To Form2.ListView1.ListItems.Count If Form2.ListView1.ListItems(n).Text = sender Then Private_Chat(n).Text1.Text = Private_Chat(n).Text1.Text & outmessage Private_Chat(n).Text1.SelStart = Len(Private_Chat(n).Text1.Text) For

23、m2.ListView1.ListItems(n).ForeColor = vbRed Form2.ListView1.ListItems(n).ListSubItems.Item(1).ForeColor = vbRed Form2.ListView1.ListItems(n).ListSubItems.Item(2).ForeColor = vbRed End If Next Loop Until InStr(sender_where2 + 1, message, "*1") = 0 End IfEnd Function2.3.1.5聊天記錄功能(1)讀取數(shù)據(jù)庫中的聊天

24、信息。添加VB的控件ADO,ADO控件建立起讀取聊天記錄的桌面型數(shù)據(jù)庫access,讀取數(shù)據(jù)庫中信息,如圖2.4。代碼如下:Public cn As ADODB.ConnectionPublic rs As ADODB.RecordsetSub adddata()Set cn = New ADODB.Connectioncn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "data.mdb;Persist Security Info=F

25、alse"cn.OpenSet rs = cn.Execute("select * from data")End Sub圖2.7數(shù)據(jù)庫的信息當(dāng)按下群聊天記錄的時(shí)候彈出對應(yīng)的RichTextBox控件如下圖圖2.8群聊天記錄對話框(2)將群聊天信息加入到數(shù)據(jù)庫。提取$與$之間的群聊天信息 If InStr(sData, "$") <> 0 Then group_chat1 = InStr(sData, "$") group_chat2 = InStr(group_chat1 + 1, sData, "$&

26、quot;) ssData = Mid(sData, group_chat1 + 3, group_chat2 - group_chat1 - 3) '=插入聊天記錄 a = CStr(Now() + Chr(10) + ssData + Chr(10) Set rs = cn.Execute("insert into data (tcp_data) values ('" & a & "')") 'tcp_data是表的列名 '=插入聊天記錄 rtbIn.Text = rtbIn.Text + Ch

27、r(10) + CStr(Now() + Chr(10) + ssData + Chr(10) rtbIn.SelStart = Len(rtbIn.Text) End If Call check_useronline(sData)Call set_privatechat2.3.1.6顯示用戶狀態(tài)功能(1)當(dāng)用戶登錄的時(shí)候,服務(wù)器會(huì)發(fā)送當(dāng)前用戶列表的信息給客戶端,協(xié)議為*用戶名*IP地址,當(dāng)IP地址為NULL時(shí),客戶端識(shí)別為沒有上線,只有不是NULL的時(shí)候才是真正有上線,對于上線的用戶,在listview中的狀態(tài)會(huì)由0變?yōu)?,表示已經(jīng)上線。同時(shí)會(huì)清空listview,將所以的用戶進(jìn)行重新的加載

28、。如圖2.6.代碼如下:Public Sub check_useronline(gData As String) account_where1 = 0 IP_where1 = 0 account_where2 = 0 IP_where2 = 0 If InStr(gData, "*") >= 1 Then Form2.ListView1.ListItems.Clear '清空列表 Do account_where1 = InStr(account_where2 + 1, gData, "*") account_where2 = InStr(

29、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) Set itmx

30、= Form2.ListView1.ListItems.Add(1, , Username) itmx.SubItems(2) = UserIP If UserIP <> "NULL" Then itmx.SubItems(1) = 1 Else itmx.SubItems(1) = 0 End If Loop Until InStr(account_where2 + 1, gData, "*") = 0 End IfEnd Sub 圖2.9用戶狀態(tài)列表(2)當(dāng)用戶退出的時(shí)候,會(huì)發(fā)送Q的字符串給服務(wù)器,告訴服務(wù)器退出,并且讓服務(wù)器發(fā)送用戶狀態(tài)

31、信息給各個(gè)在線用戶,再次刷新用戶。代碼如下:Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) tcpClient.SendData "Q" & CStr(Now() DoEvents Unload Form3 Unload Form2 Form1.ShowEnd Sub2.3.1.7文件傳輸功能基于TCP/IP協(xié)議的通信,需要分別建立客戶端應(yīng)用程序和服務(wù)器段應(yīng)用程序,大致流程如圖4-1 圖2.10客戶端與服務(wù)器數(shù)據(jù)流圖實(shí)現(xiàn)原理:發(fā)送方先獲取待傳輸文件的基本信息,主要是文件名及

32、文件長度(用于創(chuàng)建數(shù)據(jù)緩沖區(qū));然后,將其發(fā)送給接收方;接著,建立和文件一樣大小的數(shù)據(jù)緩沖區(qū),并將文件讀入;最后,將數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)發(fā)送給接收方。與此同時(shí),當(dāng)接收方接收到文件名和文件長度之后,就為其創(chuàng)建新的文件和數(shù)據(jù)緩沖區(qū);然后,接收傳輸?shù)奈募?shù)據(jù),并將其放在數(shù)據(jù)緩沖區(qū)中;最后,依次將數(shù)據(jù)緩沖區(qū)的數(shù)據(jù)寫入新創(chuàng)建的文件中。這樣便完成了不同計(jì)算機(jī)之間的文件傳輸。在本次實(shí)驗(yàn)中,于私人聊天模式里,當(dāng)勾上“打開文件傳輸通道后”,右邊button將變?yōu)榭捎?,如下圖:,圖2.11文件傳輸此時(shí)點(diǎn)擊“發(fā)送文件”按鈕,便會(huì)彈出窗體圖2.12文件傳輸界面這時(shí)窗體里的winsock控件(數(shù)組)將處于監(jiān)聽狀態(tài),執(zhí)行代

33、碼如下For j = 1 To Form2.ListView1.ListItems.Count Private_send(j).wskServer.Close Private_send(j).wskServer.LocalPort = 8000 + j Private_send(j).wskServer.ListenNext j并且若此時(shí)點(diǎn)擊“瀏覽”時(shí),將會(huì)調(diào)用系統(tǒng)里的控件“Comdlg”,執(zhí)行下段代碼Private Sub Command1_Click()With Comdlg .CancelError = True On Error GoTo OpenErr .DialogTitle =

34、“打開一個(gè)測試文件” .Filter = “所有文件 (*.*)|*.*” .Flags = &H4 .ShowOpen Text3.Text = .FileNameEnd WithOpenErr:End Sub若此時(shí)選擇的文件正確(路徑,文件存在),將可以點(diǎn)擊“發(fā)送按鈕”,已連接的對方的winsock將會(huì)發(fā)生”請求”事件,接受“請求”的話,將發(fā)生“數(shù)據(jù)到達(dá)”,相關(guān)代碼如下所示: Private Sub wskServer_ConnectionRequest(ByVal equested As Long)If Private_send(SelectNo).wskServer.State

35、 <> sckClosed Then Private_send(SelectNo).wskServer.Close Private_send(SelectNo).wskServer.Accept equestedList1.ClearList1.AddItem “已連接”Command2.Enabled = TrueEnd SubPrivate Sub wskServer_DataArrival(ByVal bytesTotal As Long)Dim WskChat As StringPrivate_send(SelectNo).wskServer.GetData WskChat

36、If WskChat = “NoThanks” Then MsgBox “對方拒收你發(fā)送的文件.”, vbExclamation, “Server”ElseIf WskChat = “OkSend” Then MsgBox “對方接受了你的文件.” & vbCrLf & vbCrLf & “單擊“確定”開始傳送”, vbInformation, “Server” GetFileNum = FreeFile LenFile = FileLen(Text3.Text) - ProBarLen = LenFile VarPlus = 0 - Open Text3.Text F

37、or Binary As #GetFileNum OnSend = True Command2.Enabled = False Call TCPSendFile(Private_send(SelectNo).wskServer, GetFileNum, SplitFile)End IfEnd Sub 若沒有連接上,我們添加了Timer控件,來監(jiān)控狀態(tài),若處于“連接關(guān)閉”狀態(tài),將重置winsock,并顯示相應(yīng)信息給用戶(例如“傳送”按鈕不可用等),如下圖:圖2.13文件傳輸中載入文件相關(guān)代碼如下: Private Sub Timer1_Timer() If Private_send(Select

38、No).wskServer.State = sckClosing Then List1.Clear List1.AddItem "對方的連接已關(guān)閉." Private_send(SelectNo).wskServer.Close Private_send(SelectNo).wskServer.LocalPort = 8000 + SelectNo Private_send(SelectNo).wskServer.Listen Command2.Enabled = False End IfEnd Sub根據(jù)上面所述的原理,是使用內(nèi)存來存儲(chǔ)數(shù)據(jù),然而,當(dāng)需要傳送的數(shù)據(jù)比較大時(shí)

39、,就不能像以上介紹的那樣,直接將整個(gè)文件放入數(shù)據(jù)緩沖區(qū)中了,我們的內(nèi)存是無法忍受用一個(gè)幾百M(fèi)B甚至上GB的空間去存儲(chǔ)那些臨時(shí)數(shù)據(jù)的。顯然,這種做法已遠(yuǎn)不能滿足我們的需求,這時(shí)可以將文件按照一定的大小,分成若干個(gè)數(shù)據(jù)包(遠(yuǎn)小于內(nèi)存的容量)。首先,設(shè)置數(shù)據(jù)包的大?。ㄈ?4K),根據(jù)文件的基本信息(主要文件的長度),計(jì)算出總共需要的數(shù)據(jù)包數(shù);然后,依次讀取同數(shù)據(jù)包一樣大小的數(shù)據(jù)到數(shù)據(jù)緩沖區(qū)中;接著,將數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù),發(fā)送到指定的計(jì)算機(jī)上;同時(shí)在另一端,建立一個(gè)數(shù)據(jù)緩沖區(qū),緩沖區(qū)的大小要根據(jù)接收到的數(shù)據(jù)來確定,依次接收客戶端傳輸過來的數(shù)據(jù)包,并將數(shù)據(jù)緩沖區(qū)的數(shù)據(jù)寫入相應(yīng)的文件中,這樣就很容易實(shí)現(xiàn)大

40、文件的傳輸了,這是一種較為常用的方法(較為容易實(shí)現(xiàn)斷點(diǎn)續(xù)傳),不過本次采用的是一種“迭代遞歸”的思想,使用自己編寫的函數(shù)SplitFile()來稍微簡單實(shí)現(xiàn)傳輸大文件,但斷點(diǎn)重傳功能將受到限制,相關(guān)代碼如下:Private Function SplitFile() As Long Dim GetCount As Long If LenFile >= 8192 Then GetCount = 8192 LenFile = LenFile - GetCount Else GetCount = LenFile LenFile = LenFile - GetCount End If VarPlu

41、s = VarPlus + GetCount ProBar.Value = (VarPlus / ProBarLen) * 100 SplitFile = GetCountEnd FunctionPrivate Sub TCPSendFile(objWinSock As Winsock, FileNumber As Integer, SendLen As Long) Dim FileByte() As Byte, i As Long ReDim FileByte(SendLen - 1) Get #FileNumber, , FileByte objWinSock.SendData FileB

42、yteEnd Sub至于顯示進(jìn)度,在私聊和傳送文件窗體里,我們添加了VB自帶的控件progressbar,進(jìn)度也根據(jù)以傳送文件的大小和總大小作簡單除法:ProBar.Value = (VarPlus / ProBarLen) * 100來顯示,圖示效果如下:圖2.14文件傳輸接收完畢圖2.15文件傳輸發(fā)送完畢2.3.2服務(wù)器2.3.2.1登錄、注冊驗(yàn)證功能雙擊服務(wù)器.exe,進(jìn)入初始界面,這里winsock將初始化,得到IP地址并且設(shè)置端口等,并對客戶端管理界面進(jìn)行初始化(此時(shí)該界面不顯示但卻已執(zhí)行相關(guān)操作,點(diǎn)擊“客戶端”界面時(shí)顯現(xiàn)):圖2.16服務(wù)器界面圖2.17客戶端管理界面當(dāng)有客戶端請求

43、連接服務(wù)器時(shí),同意的話,發(fā)生”事件到達(dá)”,服務(wù)器采取機(jī)制:判斷數(shù)據(jù)種類,并采取相關(guān)操作。代碼如下:Dim sData As String Dim sName As String tcpServer(Index).GetData sData rtbSave.SelStart = Len(rtbSave.Text) '客戶端向服務(wù)器發(fā)送已經(jīng)登錄和退出信息 '= sName = Left(sData, 1) If sName = "C" Then tcpServer(Index).SendData "C_OK" DoEvents ElseIf

44、sName = "Q" Then tcpServer(Index).SendData "Q_OK." DoEvents Call del_IP(tcpServer(Index).RemoteHostIP) '在客服端管理中刪除已退出客戶端的IP地址和上線記錄 tcpServer(Index).Close NumOnline = NumOnline - 1 End If '= '客戶端向服務(wù)器發(fā)送賬號(hào)和密碼,服務(wù)器提取賬號(hào)和密碼 '= If InStr(sData, "|") Then account_w

45、here1 = 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, "

46、#") user(0).uPWD = Mid(sData, password_where1 + 3, password_where2 - password_where1 - 3) '#密碼* Call check_account_pwd(Trim(user(0).uName), Trim(user(0).uPWD), Index) '校對數(shù)據(jù)庫中的密碼和賬號(hào)是否符合 End If '=2.3.2.2群聊功能因?yàn)閣insock“數(shù)據(jù)到達(dá)”處理,他需要判斷到達(dá)的是“登陸和退出信息”還是“已登陸用戶間的群聊天記錄”,這里我們做了個(gè)簡單的協(xié)議“InStr(sData,

47、 "$")”,相關(guān)代碼如下:If InStr(sData, "$") <> 0 Then For n = 1 To Num If tcpServer(n).State = 7 And n <> Index Then tcpServer(n).SendData sData DoEvents End If Next group_chat1 = InStr(sData, "$") group_chat2 = InStr(group_chat1 + 1, sData, "$") sData = Mi

48、d(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)End If2.3.2.3用戶信息管理功能這里我們采用單選按鈕(添加和修改)來實(shí)現(xiàn)客戶端管理和維護(hù),選擇注冊或者刪除,點(diǎn)擊“確定后”將顯示相應(yīng)功能,相關(guān)代碼如下:Private Su

49、b command1_Click() Dim i, j, k As Integer If Len(Text1.Text) = 0 Then k = MsgBox("賬戶不能為空!", 64, "提示") Exit Sub End If If Option1.Value = True Then For i = 1 To ListView1.ListItems.Count If ListView1.ListItems(i).Text = Text1.Text Then k = MsgBox("此賬戶已經(jīng)存在,不能添加!", 64, &qu

50、ot;提示") Exit Sub End If Next i Set itmx = ListView1.ListItems.Add(1, , Text1.Text) itmx.SubItems(1) = Text2.Text itmx.SubItems(2) = 0 ListView_Change1 = ListView_Change1 + 1 Call Data_Add(Text1.Text, Text2.Text) Call Con_Close k = MsgBox("已經(jīng)添加成功!", 64, "提示") Else j = ListVie

51、w1.SelectedItem.Index Form2.ListView1.ListItems(j).SubItems(1) = Text2.Text Form2.ListView1.ListItems(j).SubItems(2) = "0" Form2.ListView1.ListItems(j).SubItems(3) = "" ListView_Change1 = ListView_Change1 + 1 Call Data_Mod(Text1.Text, Text2.Text) Call Con_Close k = MsgBox("修改成功!", 64, "提示") Text3.Text = "0" End If Label7.Caption = ListView1.ListItems.CountEnd Sub 然而在刪除層面上,服務(wù)器不能刪除全部人員信息(至少得保留管理員),圖2.18刪除管理員賬號(hào)基于這種機(jī)制,在“刪除”按鈕上,我們添加如下代碼:Private Sub

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論