Qt tcp socket编程
《学习笔记》
QTcpSever用于监听,QTcpSocket用于连接客户端和服务端。
客户端连接服务端很简单,connectToHost(QHostAddress("IP", 666);,填写IP和端口就可以,连接成功后,再关联信号readyRead()就可以读取服务端发送过来的数据了
服务端首先监听某个端口,看是否有连接到该端口的机器,然后获取客户端连接的socket有两种方法:
1:关联信号newConnection(),在接受连接的过程中,应当是有一个队列,等待的连接都将放入连接队列中,在相应的槽函数中通过nextPendingConnection 函数可以得到该socket,进而可以进行通信,通信还是通过readyRead()信号,注意:这种方式返回的socket不可以用于另一个线程
2:另一种方法是继承QTcpSocket类重写incomingConnection (qintptr socketDescriptor) 函数 ,再有连接时这个函数会被系统调用,socketDescriptor 为套接字描述符,用这个描述符创建一个socket就可以了,即setSocketDescriptor 这个函数,描述符传给这个函数参数即可。
下面是我参照网上写的测试代码,可以同时有多个客户端连接到服务的同一个端口进行相互之间通信
服务端:
chatSever.h
#include <QObject>
#include <qtcpserver.h>
#include <QList>
#include <tcpsocket.h>
class chatSever : public QTcpServer
{
Q_OBJECT
public:
explicit chatSever(QObject *parent = 0, int port = 0);
//重载
void incomingConnection(int handle);
void sendMsgToClient(QString strMsg, int nLength);
private:
QList<tcpSocket*> m_clientSocketLst; //用于保存客户端链表
signals:
public slots:
void updateClientsData(QString msg, int length);
void slotDisconnected(int descriptor);
};
chatSever.cpp
#include "chatsever.h"
chatSever::chatSever(QObject *parent, int port) : QTcpServer(parent)
{
//监听
listen(QHostAddress::Any, port);
}
void chatSever::incomingConnection(int handle)
{
tcpSocket* clientSocket = new tcpSocket(this);
clientSocket->setSocketDescriptor(handle);
m_clientSocketLst.append(clientSocket);
connect(clientSocket, SIGNAL(updateClientsData(QString,int)), this, SLOT(updateClientsData(QString,int)));
//一个socket断开连接就从底层链表中删除对应的对象
connect(clientSocket, SIGNAL(disconed(int)), this, SLOT(slotDisconnected(int)));
}
void chatSever::sendMsgToClient(QString strMsg, int nLength)
{
updateClientsData(strMsg, nLength);
}
void chatSever::updateClientsData(QString msg, int length)
{
for(int i = 0; i < m_clientSocketLst.count(); ++i)
{
QTcpSocket* itemClient = m_clientSocketLst.at(i);
if(itemClient->write(msg.toLatin1().data(), length) != length)
{
qDebug() << "存在数据丢失";
continue;
}
}
}
//删除指定的socket对象
void chatSever::slotDisconnected(int descriptor)
{
qDebug() << "slotDisconnected";
for(int i = 0; i < m_clientSocketLst.count(); ++i)
{
QTcpSocket* item = m_clientSocketLst.at(i);
if(item->socketDescriptor() == descriptor)
{
m_clientSocketLst.removeAt(i);
qDebug() << QString("socket列表 = : %1").arg(m_clientSocketLst.count());
return;
}
}
}
tcpSocket.h
#include <QObject>
#include <QTcpSocket>
class tcpSocket : public QTcpSocket
{
Q_OBJECT
public:
explicit tcpSocket(QObject *parent = 0);
signals:
void updateClientsData(QString, int);
void disconed(int);
public slots:
void dataRecived();
void slotDisconnected();
};
tcpSocket.cpp
#include "tcpsocket.h"
tcpSocket::tcpSocket(QObject *parent) : QTcpSocket(parent)
{
//建立处理客户端的槽函数
connect(this, SIGNAL(readyRead()), this, SLOT(dataRecived()));
connect(this, SIGNAL(disconnected()), this, SLOT(slotDisconnected()));
}
//读取客户端信息
void tcpSocket::dataRecived()
{
while (bytesAvailable() > 0) {//貌似解决了发送方粘包的问题,加上还是好
char buf[1024] = {0};
int nLength = bytesAvailable(); //返回可用字节数
read(buf, nLength);
QString str = buf;
emit updateClientsData(str, nLength);
}
}
void tcpSocket::slotDisconnected()
{
qDebug() << "slotDisconnected";
emit disconed(socketDescriptor());
}
chatSeverUI.h
#include <QWidget>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QTcpServer>
#include "chatsever.h"
namespace Ui {
class socketSever;
}
class chatSeverUI : public QWidget
{
Q_OBJECT
public:
explicit chatSeverUI(QWidget *parent = 0);
~chatSeverUI();
void initSocket();
public slots:
// void acceptConnection();
// void readClient();
private slots:
void on_pushButton_clicked();
private:
Ui::socketSever *ui;
QTcpServer* m_sever;
QTcpSocket* m_clientConet;
chatSever* m_chatSever;
};
chatSeverUI.cpp
#include "chatseverUI.h"
#include "ui_socketsever.h"
#include <QtNetwork/qhostaddress.h>
chatSeverUI::chatSeverUI(QWidget *parent) :
QWidget(parent),
ui(new Ui::socketSever)
{
ui->setupUi(this);
m_sever = NULL;
m_clientConet = NULL;
m_chatSever = NULL;
initSocket();
}
chatSeverUI::~chatSeverUI()
{
delete ui;
}
void chatSeverUI::initSocket()
{
/*
* 方法1
m_sever = new QTcpServer(this);
m_sever->listen(QHostAddress::Any, 6666);
connect(m_sever, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
*/
//方法2
m_chatSever = new chatSever(this, 6666);
if(!m_chatSever->isListening())
{
qDebug() << QString("unable to start the sever : %1").arg(m_chatSever->errorString());
}
}
/*
void chatSeverUI::acceptConnection()
{
m_clientConet = m_sever->nextPendingConnection();
connect(m_clientConet, SIGNAL(readyRead()), this, SLOT(readClient()));
}
void chatSeverUI::readClient()
{
QString str = m_clientConet->readAll();
ui->severLabel->setText(str);
}
*/
void chatSeverUI::on_pushButton_clicked()
{
QString str = ui->severEdit->text();
//m_clientConet->write(str.toLatin1().data());
m_chatSever->sendMsgToClient(str.toLatin1().data(), str.length());
}
main函数就很简单了,只是显示了各个窗口而已
chatClientUI client1;
client1.setWindowTitle("client");
client1.show();
chatClientUI client2;
client2.setWindowTitle("client");
client2.show();
chatClientUI client3;
client3.setWindowTitle("client");
client3.show();
chatSeverUI sever;
sever.setWindowTitle("sever");
sever.show();
界面是用QTDesign设计的,这里就不再多说了,初学笔记,如果有错误的地方欢迎指正,共同进步
Qt tcp socket编程相关推荐
- 转Go语言TCP Socket编程
授权转载: Tony Bai 原文连接: https://tonybai.com/2015/11/17/tcp-programming-in-golang/ Golang的主要 设计目标之一就是面向大 ...
- golang TCP Socket编程
Golang的主要 设计目标之一就是面向大规模后端服务程序,网络通信这块是服务端 程序必不可少也是至关重要的一部分.在日常应用中,我们也可以看到Go中的net以及其subdirectories下的包均 ...
- Go语言TCP Socket编程
2019独角兽企业重金招聘Python工程师标准>>> Go语言TCP Socket编程 Golang的 主要 设计目标之一就是面向大规模后端服务程序,网络通信这块是服务端 程序必不 ...
- 基于TCP,Socket编程,模仿腾讯QQ界面,使用Java开发的一款网络聊天工具。QQ_Chat
代码下载地址 原博客地址 QQ_Chat 基于TCP,Socket编程,模仿腾讯QQ界面,使用Java开发的一款网络聊天工具. (内含报告) 工具: Eclipse.Navicat for MySQL ...
- TCP socket 编程示例
本代码为老师提供的示例程序 一.TCP socket 编程模型 二.使用TCP协议实现一个简单的通讯程序 1.服务器端 #include<stdlib.h> #include<std ...
- TCP socket编程记录(C语言)
最近使用到TCP的socket编程,记录一下思路. TCP Socket 服务器编程思路 0.初始化套接字库 1.创建套接字----------2个(服务器本身需要一个套接字,客户端要返回一个套接字) ...
- TCP/IP详解 第十二章(10) TCP Socket 编程
前言 不管面试 Java .C/C++.Python 等开发岗位, TCP 的知识点可以说是的必问的了. 任 TCP 虐我千百遍,我仍待 TCP 如初恋. 遥想小林当年校招时常因 TCP 面试题被刷, ...
- qt中socket编程
1 文章概括 在qt中借助designer设计通信界面,然后使用QTcpServer,QTcpSocket编写服务器和客户端的程序. 首先建立两个工程,一个是客户端client,另一个是服务器端ser ...
- linux网络编程IPv6socket,简单的IPv6 UDP/TCP socket编程 -- 两台Linux实现简单的ipv6通信...
配置: 1.两台linux用网线直接相连 2.手动配置两台linux的ipv6地址为: ifconfig eth0 add 2001:da8:e000::1:1:1 ifconfig eth0 add ...
最新文章
- 计算机二级vlookup引用怎么操作,VLOOKUP函数怎样引用二个条件
- K8S调度之pod亲和性
- linux mysql数据库定时备份
- Hollis原创|深入分析Java的编译原理
- OpenGL 视图和颜色的概念
- 在教学中利用计算机软件,计算机软件技术教学方法研究
- 【kafka】服务器上Kafka启动 Cannot allocate memory
- mysql存储过程 begin_MySQL存储过程的BEGIN和END
- 40个非常有创意的国外LOGO欣赏(上)
- 三枪手决斗问题的计算机解答
- STC学习:振动传感器
- linux内核nvme驱动程序,Linux中nvme驱动详解
- Python巨型文字游戏开发(带源码(1))
- 高仿TIMI页面易语言源码-已对接易游网络验证
- VOC检测格式数据分析和处理
- QNX Hypervisor —— 设备
- centos 安装virt-mannager
- LibreOJ 2060 食物链
- 关系网络lbs的应用_冒泡网王江:熟人关系将成LBS最重要商业模式
- U盘安装ubuntu20.04并优化
热门文章
- 天龙八部服务器端---共享内存的设计
- html 原型图片,可视化的JavaScript:原型继承(动图演示)
- JavaScript - Echarts经典教程-李游Leo-专题视频课程
- RPGMakerMV-事件页的出现条件和触发条件
- java-php-python-ssm-学生考勤管理系统-计算机毕业设计
- 帧同步 java_游戏同步方案——帧锁定同步
- 关于双通道,三通道,四通道内存体系结构你需要知道的事
- 使用jquery jcrop插件进行图片的截取与保存
- 【数据原理及应用 学习总结】第二章 关系数据库标准语言SQL(1)
- 什么是xml解析?xml解析的有几种常用的解析方式?