參考文檔《計算機網絡通信程序設計》—成都文理學院 信息工程學院
網絡通信程序案例(基於VB)—案例2-簡易聊天程序—貪吃的釗釗黑
指導老師:胡念青
一、任務描述
這是一個基於VB6.0實現的簡單聊天程序,它可以實現在局域網中兩臺主機間的在線聊天。
二、實現效果
說明:
本程序的運行是通過一個第三方實體爲啓動程序的,通過此實體用戶手動選擇本方是扮演客戶還是扮演服務器,並由此拉開通信的序幕。故此,本程序的測試無法在同一臺主機上完成,而必需在兩臺主機正確聯網的環境下才能完成。這是因爲第三方實體 啓動後,本機不能同時既選擇爲客戶機又選擇爲服務器主機。
因爲疫情的緣故,我並沒有在學校上課,家裏也只有一臺PC,迫使本程序只能在一臺電腦上運行,因此運行結果可能和實際有所差異,特此強調。
PC-A-服務器端
PC-B-客戶端
三、功能描述
- 點對點的字符信息簡易聊天程序;
- 採用 TCP 傳輸協議,TCP 連接建立後,雙方實體即可通過Winsock 控件提供的相關方法收發信息了。
四、實現代碼
1. ConnectFRM.frm 連接
Private Sub ClientCMD_Click()
IPtxt.Text = "Server's IP here"
'告訴用戶在此處填入服務器IP地址
Me.Caption = "Connect as Client"
IPtxt.Enabled = True
'需要填入服務器地址
nicknameTXT.Enabled = True
'使能暱稱
ServerCMD.Enabled = False
'客戶端不需要這個按鈕了
ClientCMD.Enabled = False
'客戶端不需要這個按鈕了
ConnectCMD.Enabled = True
'需要這個按鈕
End Sub
Private Sub ConnectCMD_Click()
If nicknameTXT.Text = "" Then Exit Sub
'暱稱爲空則不連接
If Me.Caption = "Connect as Server" Then
'如果是作爲服務器連接的話
ServerFRM.Winsock.Close
'關閉前面的連接
ServerFRM.Winsock.LocalPort = 1001
'187 服務器端口
ServerFRM.Winsock.Listen
'偵聽
ServerFRM.nickSERVER.Caption = nicknameTXT.Text
'暱稱一致
End If
If Me.Caption = "Connect as Client" Then
'作爲客戶端連接
If IPtxt.Text = "Server's IP here" Then Exit Sub
'需要填入IP
If IPtxt.Text = "" Then Exit Sub
'需要填入IP
ClientFRM.Winsock.Close
'關閉前面的連接
ClientFRM.Winsock.Connect IPtxt.Text, 1001
'連接服務器, 187爲端口號
ClientFRM.nickCLIENT.Caption = nicknameTXT.Text
'暱稱
End If
End Sub
Private Sub Form_Load()
ConnectCMD.Enabled = False
'連接按鈕不可用
YouripLBL.Caption = "Your IP: " & Winsock.LocalIP
'本地地址
IPtxt.Enabled = False
'IP地址欄不讓用
nicknameTXT.Enabled = False
End Sub
Private Sub ServerCMD_Click()
Me.Caption = "Connect as Server"
'窗體標題
IPtxt.Enabled = True
'需要該按鈕
nicknameTXT.Enabled = True
'需要該文本框
ServerCMD.Enabled = False
'無需該按鈕
ClientCMD.Enabled = False
'無需該按鈕
IPtxt.Enabled = False
'無需該文本框
ConnectCMD.Enabled = True
'需要該按鈕
End Sub
2. ServerFRM.frm 服務器端
'===========================================================================
'=======================從服務器獲取數據==========================
Private Sub Winsock_Close()
MainTXT.SelText = "Disconnected from Client"
senddataCMD.Enabled = False 'this wont let you send text anymore since client is disconnected
End Sub
'===========================================================================
'======================允許客戶端連接=============================
Private Sub winsock_ConnectionRequest(ByVal requestID As Long)
If Winsock.State <> sckClosed Then Winsock.Close
'關閉連接
Winsock.Accept requestID
'接受新連接
Me.Show
'顯示服務器端
Unload ConnectFRM
'隱藏ConnectFRM
Winsock.SendData "C" & nickSERVER.Caption
'發送消息,建立連接以及用戶名
ServerFRM.Caption = "Adam's Chat [Welcome, " & nickSERVER.Caption & "!]"
'renames the form approiately
MainTXT.SelText = "Connected to Client" 'displays that connection worked
End Sub
'===========================================================================
'=======================獲得客戶端數據==========================
Private Sub winsock_DataArrival(ByVal bytesTotal As Long)
Dim strData, strData2 As String
'存儲客戶端發來的消息
Call Winsock.GetData(strData, vbString)
'獲得信息
strData2 = Left(strData, 1)
'第一個字符,說明該信息的內容屬性
strData = Mid(strData, 2)
'信息
If strData2 = "T" Then
MainTXT.SelText = nickCLIENT.Caption & ": " & strData & vbCrLf
'adds the data to the txtbox
End If
If strData2 = "N" Then
nickCLIENT.Caption = strData
'loads the client's username from data sent
End If
End Sub
'===========================================================================
'========================發送消息到客戶端=========================
Private Sub senddataCMD_Click()
MainTXT.SelText = nickSERVER.Caption & ": " & dataTXT.Text & vbCrLf
'本地顯示
Winsock.SendData "T" & dataTXT.Text
'發送
dataTXT.Text = ""
'清空
End Sub
'===========================================================================
3. ClientFRM.frm 客戶端
'======================顯示斷開========================
Private Sub Winsock_Close()
MainTXT.SelText = "Disconnected to Server"
senddataCMD.Enabled = False 'this wont let you send text anymore since server is disconnected
End Sub
'=======================從服務器獲取數據==========================
Private Sub winsock_DataArrival(ByVal bytesTotal As Long)
Dim strData, strData2 As String
'客戶端存儲數據
Call Winsock.GetData(strData, vbString)
'獲取數據
strData2 = Left(strData, 1)
'strData2存儲strData中的第一個字符
'該字符表示是否爲第一條信息
strData = Mid(strData, 2)
'聊天信息
If strData2 = "C" Then
'C字符是約定顯示窗體的命令
nickSERVER.Caption = strData
'獲得服務器用戶名
Me.Show
'顯示客戶端
Unload ConnectFRM
'關閉連接窗體
Winsock.SendData "N" & nickCLIENT.Caption
'向服務器傳送客戶端的名字
ClientFRM.Caption = "Adam's Chat Client [Welcome, " & nickCLIENT.Caption & "!]"
'設置窗體標題
MainTXT.SelText = "Connected to Server"
'添加一行
'說明已經連上
End If
If strData2 = "T" Then MainTXT.SelText = nickSERVER.Caption & ": " & strData & vbCrLf
'添加從服務器過來的消息
End Sub
'========================SENDS DATA TYPED TO SERVER=========================
Private Sub senddataCMD_Click()
MainTXT.SelText = nickCLIENT.Caption & ": " & dataTXT.Text & vbCrLf
'本地顯示
Winsock.SendData "T" & dataTXT.Text
'向服務器發送消息
dataTXT.Text = ""
'清空
End Sub
五、程序解析
1.實現過程
本程序包含三個窗體分別是:ConnectFRM、ServerFRM和ClientFRM ,其中 ConnectFRM 即爲前述的第三方實體(連接窗體),也是本 VB 程序的啓動窗體,通過它我們可以爲本機選擇扮演的通信角色(客戶或服務器),並完成界面分流,即對應不同的角色該窗體界面會發生相應的變化。之後,服務器一方應先單擊聯接按鈕(Connect),使其調用 Winsock控件的 Listen方法來偵聽外部網絡的連接請求;而客戶一方也通過單擊此按鈕來發出對服務器連接請求。
在程序啓動時,只有連接窗體也就是啓動窗體 ConnectFRM 被顯示 (Show),而真正的聊天窗口(無論是客戶還是服務器:ClientFRM、ServerFRM)並未顯身。只有當雙方用戶爲其所在的主機選擇了通信實體的角色,並完成了後續相關操作(服務器偵聽、客戶端發出連接請求),且服務器接收了此連接請求後,各自的聊天窗口才自動打開。
2.核心WINSOCK解析
作爲這個程序的核心控件WINSOCK,我們來看看它的一些常用屬性、事件和方法。利用WinSock控件可以與遠程計算機建立連接,並通過用戶數據文報協議 (UDP)或者傳輸控制協議 (TCP)進行數據交換。這兩種協議都可以用來創建客戶與服務器應用程序。
- LocalIP方法:用於返回本地機器的 IP 地址;
- LocalPort方法:設置服務器端口;
- Connect方法:連接服務器;
- Listen方法:偵聽;
- Close方法:關閉當前連接;
- SendData方法:發送一條數據給另一臺主機;
- GetData方法:獲得數據;
- DataArrival事件:存儲客戶端發來的消息。
數據的發送是在鍵盤事件觸發後完成的,其中調用了Winsock 控件的SendData 方法;而數據的接收是在 Winsock 控件的 DataArrival 事件觸發後完成的,其中調用了Winsock的 GetData 方法。