二、编程
1.登录
使用QQ的人都知道,用QQ聊天第一步是登录,这一步看似简单,其实程序做了不少事情。当用户启动QQ聊天客户端程序,出现登录界面,用户输入用户名和密码,点击登录按钮后,在用户机上的客户端程序首先请求与服务端程序建立连接,服务端程序接受客户端程序连接请求。客户端程序在确保已和服务端程序建立连接后发送登录时用户输入的用户名和密码,服务端程序收到后,根据用户信息数据库中数据验证。如果验证为合法用户,客户端程序则显示聊天窗体,并从服务端获取在线好友信息,以便直接与各在线好友逐一建立新的通信机制,实现好友间直接通信。具体实现步骤如下:
(1)监听
先在窗体上加一个Winsock控件,名称设为“WinsockServer”。由于服务端需要和所有客户端通信,需要很多Winsock控件,因此把刚加入的Winsock控件WinsockServer改为数组,只要将Winsock控件的Index属性设为0即可,此时WinsockServer数组只有一个元素,以后可根据需要动态增减。当窗体载入时,只会创建WinsockServer(0)这一个Winsock控件实例。作为服务端程序,首先要有一个Winsock用于监听客户端的连接请求,自然就用WinsockServer(0)作为监听Winsock,所以先要设置其通信协议为TCP,然后设置本地端口,以便客户端通过该端口与服务端连接,最后通过Listen方法监听。
Private Sub Form_Load()
ConDB’ 自定义函数ConDB用于和存储用户信息的数据库连接,具体实现见源程序。
WinsockServer(0).Protocol = sckTCPProtocol ‘设置通信协议为TCP
WinsockServer(0).LocalPort = 8888 ‘设置本地端口
WinsockServer(0).Listen’ 监听
End Sub
(2)请求与服务端程序建立连接
当用户输入用户名和密码单击登录按钮后,在用户机上的客户端程序所做的事情是先请求与服务端程序建立连接,这需要先在客户端程序的登录窗体上加一个Winsock控件,名称设为“WinsockClient”。然后设置通信协议,要连接的服务器IP地址,远程端口号要与服务端监听所设置的本地端口一致,最后通过Connect方法请求与服务端程序建立连接。
Private Sub Command1_Click() ‘单击登录按钮事件
WinsockClient.Protocol = sckTCPProtocol ‘设置通信协议为TCP
WinsockClient.RemoteHost = "127.0.0.1" ‘要设置正确的服务器IP地址
WinsockClient.RemotePort = 8888 ‘远程端口
WinsockClient.Connect ‘请求与服务端程序建立连接
End Sub
(3)接受客户端程序连接请求
当客户端请求与服务端程序建立连接时,处于监听状态的服务端会收到消息触发ConnectionRequest事件,所以服务端程序接受客户端程序连接请求的工作在ConnectionRequest事件方法中完成。由于WinsockServer(0)专用于监听,所以要新加载一个Winsock控件与该客户端通信,为了保留每个在线客户的信息,我定义了一个OnlineUserInformation结构类型的数组OnlineUserInfo,它和Winsock控件数组相对应,比如OnlineUserInfo(i)中存放的是与WinsockServer (i)通信客户端的信息,其中OnlineUserInfo(i).bUsed表示WinsockServer (i)控件是否已被载入在与某个客户端通信使用,如未使用,则通过Load方法将WinsockServer (i)控件动态载入,随后调用Accept方法接受客户端程序连接请求。其中MaxOnlineUser是一个常量,表示最大在线用户数量。
Type OnlineUserInformation
bUsed As Boolean ‘对应下标的Winsock控件是否已被载入在用
UserID As String ‘对应的用户ID
IPAddr As String ‘对应的客户机IP地址
bLogined As Boolean ‘对应的用户是否登录
End Type
Public OnlineUserInfo(1 To MaxOnlineUser) As OnlineUserInformation
Private Sub WinsockServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
If Index = 0 Then
For i = 1 To MaxOnlineUser
If Not OnlineUserInfo(i).bUsed Then
Load WinsockServer(i)
WinsockServer(i).Accept requestID
OnlineUserInfo(i).bUsed = True
Exit For
End If
Next i
End If
End Sub