基于正点原子教程,个人改编一点点(先写着,还没学客户端来验证)
QTcpServer 服务端,下控制多个socket
QTcpSocket 可以理解为一个TCP连接
使用客户端的流程为
1.包含network和include
2.声明QTcpServer信号
整个流程都要使用QTcpServer对象,所以在自己的widget里声明指针,在构造函数里添加内存申请,绑定父对象widget用于显示等
3.监听端口和停止监听
新建服务端后需要监听ip端口,在ui文件建立两个输入line edit和一个pushbutton开始监听
转到开始监听的clicked槽函数
服务器开始监听输入的ip端口
断开监听按钮:调用close()函数
Qlist见下面5,这里说一下为什么要这样做,测试中发现光tcpServer->close()无法关闭,仍然可以连接,查询帮助后发现
上面写的是不再监听(新)到来的连接,而对当前的连接没有操作,所以如果要关闭全部当前连接,则需要在服务器端把连接的socket全close后再TcpSocket->close()
4.有客户端连接以后,保存socket
客户端连接时,会发出一个newConnection()信号
使用一个槽函数去连接这个信号(名称随意,仅为了较为匹配信号)
编写槽函数内容
为什么说是保存socket,因为当服务器server监听到后已经新建了socket,我们只需要获取他来建立我们自定义的内容
[virtual] QTcpSocket *QTcpServer::nextPendingConnection()
Returns the next pending connection as a connected QTcpSocket object.
The socket is created as a child of the server, which means that it is automatically deleted when the QTcpServer object is destroyed. It is still a good idea to delete the object explicitly when you are done with it, to avoid wasting memory.
0 is returned if this function is called when there are no pending connections.
Note: The returned QTcpSocket object cannot be used from another thread. If you want to use an incoming connection from another thread, you need to override incomingConnection().
See also hasPendingConnections().
使用一个tcpSocket获取服务器server监听到后新建的指针(textBrowser是一个显示框用来显示获得的数据内容)
5.读取接受的数据
下面开始编写我们自己需要的内容
tcpsocket接受到数据允许读取时候会发出readyRead()信号,在widget新建一个槽函数将其打印出来
当连接上/断开时会发出stateChanged的信号,我们根据这个新建一个槽函数来进行一些显示和socket内存的释放(socket应该是第一次连接时创建,客户端断开时不释放所以才会在这里释放,如果有空我会进行一个简单的验证)
注意这个send(),在槽函数里可以调用sender()函数获取发送对象,发送对象就是信号和槽函数绑定时connect的第一个参数,也就是发送可读取信号的那个tcpsocket对象,数据的读写对readwrite等io函数重载,和操作文件一样的逻辑
更正:此处的delete会导致出现错误,请使用(QTcpSocket*)send->deletelater()
函数1:可以接收数据后接受数据readAll(),添加到textBrowser显示
函数2:状态改变后打印状态,如果是客户端断连后释放tcpSocket对象的内存
6.添加发送数据部分
发送按钮添加槽函数,向所有连接的端口发送数据
解释一下这段代码,前面已经说了新的socket实际上已经在tcpserver对象中被建立了,我们只需要调用他,QList<QTcpSocket *>模板建立一个成员为socket指针的链表容器,findChildren<QTcpSocket *>()是一个函数模板,找寻tcpserver对象的所有类型为tcpsocket*的子类返回到我们新建的容器,那么我们就获得访问所有已连接socket(因为前面的代码已经把断开的socket都delete了),再通过for循环对每个socket进行write(数据发送),这样我们的服务器就完成了
使用客户端的流程为
客户端事实上就是一个去主动连接的socket,由于整个过程都要使用此socket,那么同服务器,在widget添加TcpSocket的指针,一样的初始化,区别只是连接和断开的过程
1.客户端的连接
调用connectToHost(ip,端口)方法去连接
1.客户端的断开
关闭