1. <li id="3se62"></li>
      <th id="3se62"></th>

      <progress id="3se62"></progress>
         你好,歡迎來到電腦編程技巧與維護雜志社! 雜志社簡介廣告服務讀者反饋編程社區  
        合訂本訂閱
         
         
        您的位置:雜志經典 / 網絡與通信
        QQ聊天程序的網絡通信原理及編程(中)
         

        (4)發送登錄的用戶名和密碼

        客戶端程序在服務端程序接受連接后會收到消息觸發Connect事件,對客戶端而言在Connect事件方法中發送登錄用戶名和密碼是最佳時機,為了使接收數據的一方明白收到的數據代表什么含義,每條數據最前面有代表不同含義的數據含義標記字符串,每條數據后有相同的數據結束標記符,每條數據中各子數據間有子數據分割標記符。各數據含義標記字符串如下:

        Public Const OnlineFriendIPID = "FriendIPID" '表示本數據中包含在線好友的IP地址和ID

        Public Const Login = "User Login" '表示本數據中包含登錄用戶的用戶ID和密碼

        Public Const NotUser = "IsNot User"  '本數據含義為“不是合法用戶”

        Public Const  IsUser = "ThisIsUser"  '本數據含義為“是合法用戶”

        為了識別數據含義方便,含義標記字符串長度一致,我這里采用的長度為10。

        Public Const HeadLength = 10

        關于分割標記符和結束標記符,我采用數值12轉字符的方法,因為它們轉成的字符不是普通字符,不會和傳送的數據如用戶ID、密碼、IP地址等字符串數據混淆。

        具體發送數據通過SendData方法進行,發送登錄用戶名和密碼的語句如下,數據的格式為:數據含義標記字符串+用戶名+分割標記符+密碼+結束標記符。

        Private Sub WinsockClient_Connect()

        WinsockClient.SendData Login & TextUsername.Text & Chr(1) & TextPassword.Text & Chr(2)

        End Sub

        (5)接收收據

        當有數據到達時,程序會收到消息觸發DataArrival事件,所以不論服務端還是客戶端程序接收數據的工作在DataArrival事件方法中完成。具體接收數據使用GetData方法進行,為了防止客戶端發送來的數據太多,服務端來不及處理,我定義了一個字符串數組BufferRecv,該數組與WinsockServer控件數組對應,WinsockServer(Index) 控件收到的數據添加在BufferRecv(Index)中,然后通過結束標記符在BufferRecv(Index)中取出一條條數據進行分析。如果是客戶登錄,則獲取用戶名和密碼,然后通過自定義函數Lookfor在數據庫中驗證。如果驗證為合法用戶,則發送“是合法用戶”數據標記,然后將用戶ID和用戶機器的IP等信息置于一個在線用戶信息的結構數組中備用。然后通過自定義函數GetFriend在數據庫中獲取該用戶的所有好友ID及好友人數,并根據在線用戶信息數組逐一判斷各個好友是否在線,如果在線,則將在線好友的IDIP地址發送給剛登錄的客戶,同時也將剛登錄客戶的IDIP地址發送給在線好友,以便他們相互之間能夠通信。如果驗證為非法用戶,則發送“不是合法用戶”數據標記,并將與該客戶通信用的Winsock控件卸載。

        Private Sub WinsockServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)

        Dim tmpstr As String

        Dim EndFlagLoc As Integer ‘結束標記所處位置變量

        If Index = 0 Then Exit Sub

        WinsockServer(Index).GetData tmpstr, , bytesTotal ‘接收收據存入tmpstr

        BufferRecv(Index) = BufferRecv(Index) & tmpstr ‘將收到的數據添加在BufferRecv(Index)

        EndFlagLoc = InStr(BufferRecv(Index), Chr(2)) ‘BufferRecv(Index)中尋找第一個結束標記符的位置

        While EndFlagLoc > 0

            BufferRecv(Index)中取第一個結束標記符左邊的數據,即第一條數據。

        strMsg = Left$(BufferRecv(Index), EndFlagLoc - 1)

        獲取本條數據前面的數據含義標記字符串以分析本條數據的含義。

            Select Case Left$(strMsg, HeadLength) 

                Case Login ‘如果是登錄數據

                    Dim tmpPassWord As String

                    Dim tmpUserID As String

                    通過Mid方法取得數據含義標記字符串之后分割標記符之前的數據,即登錄用戶名。

                    tmpUserID = Mid(strMsg, HeadLength + 1, InStr(strMsg, Chr(1)) - 1 - HeadLength)

                     通過Mid方法取得分割標記符之后的數據,即登錄密碼。

                    tmpPassWord = Mid(strMsg, InStr(strMsg, Chr(1)) + 1)

        通過自定義函數Lookfor在數據庫中查詢該用戶名密碼是否存在,如存在則發送含義為“是合法用戶”的數據,Lookfor函數的具體實現見源程序。

                    If Lookfor(tmpUserID, tmpPassWord) Then

                        WinsockServer(Index).SendData IsUser & Chr(2)

                        DoEvents

        將客戶端的IP地址和用戶ID等信息置于一個有關在線用戶信息的結構數組中備用,并設置登錄標志變量bLoginedTrue。

                        OnlineUserInfo(Index).IPAddr = WinsockServer(Index).RemoteHostIP

                        OnlineUserInfo(Index).UserID = tmpUserID

                          OnlineUserInfo(Index).bLogined = True

                        Dim AllFriendID As String

                        Dim FriendID As String

                        Dim FriendCount As Integer

                        Dim ToldFriendCount As Integer

        然后通過自定義函數GetFriend在數據庫中獲取該用戶的所有好友的ID及好友人數,分別放在參數AllFriendIDFriendCount中。

                        If GetFriend(tmpUserID, AllFriendID, FriendCount) Then

        然后根據在線用戶信息數組用InStr函數逐一判斷在線用戶是否是該用戶的好友。

                            For i = 1 To MaxOnlineUser

                                If OnlineUserInfo(i).bLogined Then

                                    If InStr(AllFriendID, OnlineUserInfo(i).UserID) > 0 Then

        如果是,則將在線好友的IDIP地址發送給剛登錄的客戶。發送數據的格式為:數據含義標記字符串+IP地址+分割標記符+用戶ID+結束標記符。

                                        If WinsockServer(Index).State = sckConnected Then

                                            WinsockServer(Index).SendData OnlineFriendIPID & OnlineUserInfo(i).IPAddr & Chr(1) & OnlineUserInfo(i).UserID & Chr(2)

                                            DoEvents

                                        End If

        同時也將剛登錄客戶的IDIP地址發送給在線好友,以便他們相互之間能夠通信。

                                        If WinsockServer(i).State = sckConnected Then

                                            WinsockServer(i).SendData OnlineFriendIPID & OnlineUserInfo(Index).IPAddr & Chr(1) & OnlineUserInfo(Index).UserID & Chr(2)

                                            DoEvents

                                        End If

                                        ToldFriendCount = ToldFriendCount + 1

                                    End If

                                End If

                                If ToldFriendCount = FriendCount Then Exit For

                            Next i

                        End If

        如果驗證為非法用戶,則發送含義為“不是合法用戶”的數據標記,并將與該客戶通信用的Winsock控件卸載。

                    Else

                        WinsockServer(Index).SendData NotUser & Chr(2)

                        DoEvents

                        OnlineUserInfo(Index).bUsed = False

                        WinsockServer(Index).Close

                        Unload WinsockServer(Index)

                    End If

        然后從BufferRecv(Index)中刪除已分析的這條數據,繼續分析下一條數據。

            BufferRecv(Index) = Mid(BufferRecv(Index), EndFlagLoc + 1)

            EndFlagLoc = InStr(BufferRecv(Index), Chr(2))

        Wend

        End Sub

        (6)客戶端接收數據

        客戶端程序在收到數據后,對每條數據進行分析。如果不是合法用戶,則顯示“你不是合法用戶!”;如果是合法用戶,則隱藏登錄窗體,顯示聊天窗體;如果是在線好友信息,則提取該在線好友的IDIP地址,然后通過自定義過程AddConnectOnlineFriend將該在線好友信息保存,并與該在線好友建立連接。

        Private Sub WinsockClient_DataArrival(ByVal bytesTotal As Long)

        Dim tmpstr As String

        Dim EndFlagLoc As Integer

        WinsockClient.GetData tmpstr, , bytesTotal

        BufferCmd = BufferCmd & tmpstr

        EndFlagLoc = InStr(BufferCmd, Chr(2))

        While EndFlagLoc > 0

            strMsg = Left$(BufferCmd, EndFlagLoc - 1)

            Select Case Left$(strMsg, HeadLength)

                Case NotUser

                    MsgBox "你不是合法用戶!"

                Case IsUser

                    MyID = TextUsername.Text ‘將用戶ID保存在MyID中以備后用

                    loginfrm.Hide

                    Form1.Show

                 Case OnlineFriendIPID

                    Dim UserIP As String

                    Dim UserID As String

                    UserIP = Mid(strMsg, HeadLength + 1, InStr(strMsg, Chr(1)) - 1 - HeadLength)

                    UserID = Mid(strMsg, InStr(strMsg, Chr(1)) + 1)

                    Form1.AddConnectOnlineFriend UserID, UserIP

            End Select

            DoEvents

            BufferCmd = Mid(BufferCmd, EndFlagLoc + 1)

            EndFlagLoc = InStr(BufferCmd, Chr(2))

        Wend

        End Sub

        自定義過程AddConnectOnlineFriend定義在聊天窗體中,首先將服務端發來的在線好友的IP地址和ID等保存在一個有關在線好友信息的結構型數組OnlineFriendInfo中,然后加載一個Winsock控件WinsockClientClient(i),用于給在線好友發送聊天信息,加載后同樣要設置協議、遠程IP地址、遠程端口,然后以客戶端方式請求與該好友連接。

        Public Sub AddConnectOnlineFriend(UserID As String, UserIP As String)

            For i = 1 To MaxOnlineFriend

                If Not OnlineFriendInfo(i).bUsed Then

                    OnlineFriendInfo(i).bUsed = True

                    OnlineFriendInfo(i).IPAddr = UserIP

                    OnlineFriendInfo(i).UserID = UserID

                    Load WinsockClientClient(i)

                    WinsockClientClient(i).Protocol = sckTCPProtocol

                    WinsockClientClient(i).RemotePort = 6000

                    WinsockClientClient(i).RemoteHost = OnlineFriendInfo(i).IPAddr

                    If WinsockClientClient(i).State = sckClosed Then WinsockClientClient(i).Connect

                    Exit For

                End If

            Next i

        End Sub

        所以在客戶端程序中為了以服務端方式接受在線好友的連接,在聊天窗體加載時,要設置WinsockClientServer(0)這個Winsock控件,以便監聽在線好友的連接。

        Private Sub Form_Load()

        WinsockClientServer(0).Protocol = sckTCPProtocol

        WinsockClientServer(0).LocalPort = 6000

        WinsockClientServer(0).Listen   '開始監聽

        End Sub

          推薦精品文章

        ·2023年7月目錄
        ·2023年6月目錄 
        ·2023年5月目錄
        ·2023年4月目錄 
        ·2023年3月目錄 
        ·2023年2月目錄 
        ·2023年1月目錄 
        ·2022年12月目錄 
        ·2022年11月目錄 
        ·2022年10月目錄 
        ·2022年9月目錄 
        ·2022年8月目錄 
        ·2022年7月目錄 
        ·2022年6月目錄 

          聯系方式
        TEL:010-82561037
        Fax: 010-82561614
        QQ: 100164630
        Mail:gaojian@comprg.com.cn

          友情鏈接
         
        Copyright 2001-2010, www.1wcdp.top, All Rights Reserved
        京ICP備14022230號-1,電話/傳真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
        地址:北京市海淀區遠大路20號寶藍大廈E座704,郵編:100089 
        1. <li id="3se62"></li>
          <th id="3se62"></th>

          <progress id="3se62"></progress>
            操美女小骚逼