QQ聊天程序的网络通信原理及编程

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
End Type
Public OnlineUserInfo(1 To MaxOnlineUser) As OnlineUserInformation
Private Sub WinsockServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
1.在服务端和客户端之间(一对多)
用于客户端程序登录,验证用户密码,获取其它在线好友信息等等。
2.在客户端和客户端之间(多对多)
用于在线好友间直接通信聊天。此时每个客户端程序上既有实现服务端功能的部分,又有实 现客户端功能的部分,前者用于接收聊天数据,后者用于发送聊天数据。
在用 C/S 模式进行通信时,作为客户端在请求与服务端连接时需要知道服务端的 IP 地址, 腾讯公司的服务器具有固定的公网地址,这没有问题。但是在客户端和客户端之间通信时, 每个用户的 IP 地址都是 ISP 所给的临时地址,无法固定,那么某个用户要与另一个用户连 接时,怎么知道对方的 IP 地址呢?当一个用户连接到 Internet 后,获得了一个临时的公网 地址,当登录到 QQ 时,QQ 服务端会获得该上线用户的 IP 地址,然后告知其他要与该上线 用户聊天的用户,其他用户就可以连接该用户与之直接通信了。
本程序中用到的 Winsock 控件如下表:
控件名 是否为数组
作用 在哪个程序中
WinsockServer 是 用于和客户端通信 服务端程序
WinsockClient 否 用于和服务端通信 客户端程序
WinsockClientServer 是 用于接收在线好友的聊天信息 客户端程序
WinsockClientClient 是 用于向在线好友发送聊天信息 客户端程序
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
由于本文的主题是网络通信,所以本程序中所涉及的一些其它功能如数据库访问等的实现, 限于篇幅不进行阐述,有兴趣的读者可以参考源程序。为了阐述方便,本程序中服务端只用 了一个窗体,客户端只用了两个窗体,分别是登录窗体和聊天窗体。
接下来我们按照 QQ 聊天程序的所需实现的功能一步步编程实现,其中服务端程序和客户端 程序没有分开阐述,而是按照所应实现功能的先后次序一并阐述,便于读者理解及按此顺序 编程调试。
Type OnlineUserInformation
bUsed As Boolean ‘对应下标的 Winsock 控件是否已被载入在用
UserID As String ‘对应的用户 ID
IPAddr As String ‘对应的客户机 IP 地址
bLogined As Boolean ‘对应的用户是否登录
Exit For
End If
Next i End If End Sub
(4)发送登录的用户名和密码 客户端程序在服务端程序接受连接后会收到消息触发 Connect 事件,对客户端而言在 Connect 事件方法中发送登录用户名和密码是最佳时机,为了使接收数据的一方明白收到的数据代表 什么含义,每条数据最前面有代表不同含义的数据含义标记字符串,每条数据后有相同的数 据结束标记符,每条数据中各子数据间有子数据分割标记符。各数据含义标记字符串如下:
制,实现好友间直接通信。具体实现步骤如下:
(1)监听
先在窗体上加一个 Winsock 控件,名称设为“WinsockServer”。由于服务端需要和所有客 户端通信,需要很多 Winsock 控件,因此把刚加入的 Winsock 控件 WinsockServer 改为数组, 只要将 Winsock 控件的 Index 属性设为 0 即可,此时 WinsockServer 数组只有一个元素,以 后可根据需要动态增减。当窗体载入时,只会创建 WinsockServer(0)这一个 Winsock 控件 实例。作为服务端程序,首先要有一个 Winsock 用于监听客户端的连接请求,自然就 用 WinsockServer(0)作为监听 Winsock,所以先要设置其通信协议为 TCP,然后设置本地端口, 以便客户端通过该端口与服务端连接,最后通过 Listen 方法监听。
WinsockServer(0).Listen’ 监听
End Sub
(2)请求与服务端程序建立连接
当用户输入用户名和密码单击登录按钮后,在用户机上的客户端程序所做的事情是先请求与 服务端程序建立连接,这需要先在客户端程序的登录窗体上加一个 Winsock 控件,名称设为 “WinsockClient”。然后设置通信协议,要连接的服务器 IP 地址,远程端口号要与服务端 监听所设置的本地端口一致,最后通过 Connect 方法请求与服务端程序建立连接。
Private Sub Form_Load()
ConDB’ 自定义函数 ConDB 用于和存储用户信息的数据库连接,具体实现见源程序。
WinsockServer(0).Protocol = sckTCPProtocol ‘设置通信协议为 TCP
WinsockServer(0).LocalPort = 8888 ‘设置本地端口
在 Win32 平台上,对于众多的基层网络协议,Winsock 是访问它们的首选接口。如果想从头 开发一个网络通信应用程序,TCP/IP 就是首选协议之一。为了保证可靠的数据传输,宜选 择 TCP 协议。在开发工具方面,VC 是我的首选,但 VB 可能拥有更多的使用者,所以我用 VB6.0 作为开发工具编程实现,以便更多的读者能够理解。喜欢 VC 的的读者要将其转化成 VC 下的 代码也很容易。在 VB 中有一个 Winsock 控件,它为 VB 网络编程提供了一条便捷的途径。
Private Sub Command1_Click() ‘单击登录按钮事件
WinsockClient.Protocol = sckTCPProtocol ‘设置通信协议为 TCP
WinsockClient.RemoteHost = "127.0.0.1" ‘要设置正确的服务器 IP 地址
WinsockClient.RemotePort = 8888 ‘远程端口
二、编程ቤተ መጻሕፍቲ ባይዱ
1.登录
使用 QQ 的人都知道,用 QQ 聊天第一步是登录,这一步看似简单,其实程序做了不少事情。 当用户启动 QQ 聊天客户端程序,出现登录界面,用户输入用户名和密码,点击登录按钮后, 在用户机上的客户端程序首先请求与服务端程序建立连接,服务端程序接受客户端程序连接 请求。客户端程序在确保已和服务端程序建立连接后发送登录时用户输入的用户名和密码, 服务端程序收到后,根据用户信息数据库中数据验证。如果验证为合法用户,客户端程序则 显示聊天窗体,并从服务端获取在线好友信息,以便直接与各在线好友逐一建立新的通信机
Public Const '表示本数据中包含在线好友的 IP 地址和 ID Public Const Login = "User Login" '表示本数据中包含登录用户的用户 ID 和密码 Public Const NotUser = "IsNot User" '本数据含义为“不是合法用户” Public Const IsUser = "ThisIsUser" '本数据含义为“是合法用户” 为了识别数据含义方便,含义标记字符串长度一致,我这里采用的长度为 10。 Public Const HeadLength = 10 关于分割标记符和结束标记符,我采用数值 1 和 2 转字符的方法,因为它们转成的字符不是 普通字符,不会和传送的数据如用户 ID、密码、IP 地址等字符串数据混淆。 具体发送数据通过 SendData 方法进行,发送登录用户名和密码的语句如下,数据的格式为: 数据含义标记字符串+用户名+分割标记符+密码+结束标记符。 Private Sub WinsockClient_Connect() WinsockClient.SendData Login & TextUsername.Text & Chr(1) & TextPassword.Text & Chr(2) End Sub (5)接收收据 当有数据到达时,程序会收到消息触发 DataArrival 事件,所以不论服务端还是客户端程序 接收数据的工作在 DataArrival 事件方法中完成。具体接收数据使用 GetData 方法进行,为
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 是一个常量,表示最大在线用户数量。
了防止客户端发送来的数据太多,服务端来不及处理,我定义了一个字符串数组 BufferRecv, 该 数 组 与 WinsockServer 控 件 数 组 对 应 , WinsockServer(Index) 控 件 收 到 的 数 据 添 加 在 BufferRecv(Index)中,然后通过结束标记符在 BufferRecv(Index)中取出一条条数据进行分析。 如果是客户登录,则获取用户名和密码,然后通过自定义函数 Lookfor 在数据库中验证。如 果验证为合法用户,则发送“是合法用户”数据标记,然后将用户 ID 和用户机器的 IP 等信息 置于一个在线用户信息的结构数组中备用。然后通过自定义函数 GetFriend 在数据库中获取 该用户的所有好友 ID 及好友人数,并根据在线用户信息数组逐一判断各个好友是否在线, 如果在线,则将在线好友的 ID 及 IP 地址发送给刚登录的客户,同时也将刚登录客户的 ID 及 IP 地址发送给在线好友,以便他们相互之间能够通信。如果验证为非法用户,则发送“不 是合法用户”数据标记,并将与该客户通信用的 Winsock 控件卸载。
QQ 聊天程序的网络通信原理及编程
、 QQ 聊天程序采用的是 C/S 通信模式,即客户/服务模式,它把一个应用划分成功能不同的两 个部分,分别在不同的计算机上运行,其中一个为服务端程序,用来响应和提供固定的服务, 一个为客户端程序,用来向服务端提出请求和要求某种服务。在数量关系上,通常有一对一 的(即一个服务端程序和一个客户端程序之间通信),也有一对多的(即一个服务端程序和 多个客户端程序之间通信),也有多对多的(即多个服务端程序和多个客户端程序之间通信)。 所谓服务端程序、客户端程序也是相对的概念,有时在一个程序中既有服务端又有客户端的 功能。QQ 聊天程序分成了两个程序,一个安装在腾讯公司的服务器上,我们称之为服务端 程序,一个安装在 QQ 用户的计算机上,我们称之为客户端程序。在许多介绍网络通信编程 的书籍中有关网络聊天的例子,当一个客户要与另一个客户聊天时,第一个客户先把聊天数 据发送给服务器,然后服务器再把聊天数据转发给第二个客户,服务器好像一个中转站,这 在客户数量比较少时,服务器还能承受,在客户数量比较多时,服务器肯定要瘫痪。何况客 户之间还要传送文件、语音聊天、视频聊天等等,为了减少服务器的压力,各客户端之间需 要直接通信。
相关文档
最新文档