一. 前言
先上图关于QT通信网上能搜到的,基本都是清一色的客户端到服务端的通信,至于客户端与客户端的通信,少之又少,我反正是基本找不到,要有也只是给一张图,博主也是想了很长时间,也算是想出来了,所以当你看到这里,我再次强烈建议你收藏。
关于客户端与服务端之间的通信,这个在csdn倒是有很多资料的,基本内容都一样,如果不了解客户端到服务端之间的通信,可以先去复习一下。
二. 正文
1. 客户端与客户端通信思路
先简单叙述一下单纯的客户端到服务端通信的流程
第一步:服务端:
设置ip设置端口开始监听
第二步:客户端:
设置ip设置端口发送TCP请求
经过三次握手之后,客户端建立与服务端的通信,这就是单纯的客户端和服务端建立通信过程。
现在我们要做的就是要多个用户可以连接服务端,并且通过服务端进行客户端与客户端的通信。
这里就大大加大了难度,单纯的客户端与服务端通信,无需考虑或者说是识别是那个用户,因为只是作为一个例子出现。
以QQ举例
一个QQ就是一个客户端,服务端就要考虑识别是哪个用户,要知道一条信息是来自哪个客户端并发送给哪一个客户端的。
一个QQ又有N个好友,一个客户端收到的消息又要考虑如何到达正确的好友聊天窗口。
这都是本篇接下来将要表达的,但是这篇只考虑双方在线的情况下进行通信,不考虑不在线的情况,关于不在线的情况,客户端如何在上线后继续接受消息,这一功能可以交给数据库来做,本篇暂不在讨论。
在一个简单的客户端与服务端通信例子中,服务端无需识别用户,因为用户唯一,那么多个客户端登录如何识别?可以使用ip吗,不行,想一想,当两个客户端在同一台电脑登录时,ip将是相同,如何做到唯一值?使用 账号+IP+端口 确定唯一值,来说一说为什么需要三个组合值才能确定客户端。
A,B作为客户端,S作为服务端
A,B在同一台电脑登录,假设IP值都是10.13.128.122
仅使用IP无法识别,再加一个端口号呢?
这个端口号并不是客户端与服务端通信时设置的端口号,而是服务端为每一个请求连接的客户端分配的闲置端口号。
要让服务器知道一条信息是来自哪个客户端并发送给哪一个客户端的,可以在客户端发送信息之前给消息加上前缀。
A要给B发一句”你好“,这条信息在发送给服务端之前,被加工成为“1111111112345678你好”。
前8位为目的地账号,再往后8位为发送者账号。
服务端分配的随机端口号只有服务器知道,客户端是无法获取,或者只能让服务器传回去。
所以服务端收到的信息是”1111111112345678你好“,服务端通过解析知道了要发生给11111111这个账号,也就是B,并将前8位截掉。
但是问题来了,服务端怎么知道11111111对应哪个客户端,哪个IP,哪个端口号,所以除了IP,端口,还需要一个账号才能确定唯一用户。
客户端第一次连接服务端,将自己的账号发送,表明身份,服务端将账号,IP,生成的端口保存在数据库,服务端知道要发生给11111111这个账号,就去数据库查询该账号对应的端口号,因为IP可能相同,但是端口号不会相同,至此服务端正确的将信息发送给B。
B与服务端的连接是存在于主界面的,所以是B的主界面收到一条信息“12345678你好”。
但是B有很多好友,每一个好友都是一个聊天窗口,如何将消息显示在正确对应的窗口,就要用到信息的前8位,表示这条信息要显示在标记为12345678的窗口。
至此整个流程完成。
读完之后读者可能有疑问,服务器怎么连接多个客户端,这里是单纯的连接,普通的连接是服务端监听请求,有请求就创建套接字,所以有几个请求,就创建几个套接字就可以实现多个客户端连接。
2. 代码实现
(1)服务端的实现
省略ui变量操作,头文件
再来看cpp文件
(2)客户端的实现
主界面头文件
主界面cpp文件
聊天窗口
主窗口绑定信号槽
最后说一下代码中的信号槽
无论是父子窗口还是两个独立窗口,信号槽都是可以使用的,
A想调用B的函数,就在A里面发送信息,在B里面连接信号槽即可。
所有文章源码已整体打包上传至github,求星星!
重要的东西说两遍,资料少,建议收藏!
最后IU镇楼
领取专属 10元无门槛券
私享最新 技术干货