Qt tcp socket编程
来源:互联网 发布:iphone6网络连接不上 编辑:程序博客网 时间:2024/06/05 14:36
《学习笔记》
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);
};
#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编程
- QT Socket编程--TCP Server
- QT TCP下的socket编程
- 【引用】QT TCP下的socket编程
- QT基于TCP的Socket编程
- Socket编程练习(TCP)
- SOCKET TCP 编程
- Socket-TCP编程
- TCP socket编程模型
- TCP Socket服务器编程
- 网路编程-TCP-Socket
- socket编程之tcp
- 基本TCP socket编程
- Socket TCP 编程
- Socket 编程(TCP)
- TCP Socket服务器编程
- TCP Socket服务器编程
- socket的tcp编程
- 整合springMVC+mybatis
- Neural Networks and Deep Learning 学习笔记(六)
- 整数划分
- iOS 从一串文字中找到某个文字,设置某文字的颜色/富文本问题
- Jenkins自动化测试:使用临时文件实现不同测试用例间的变量传递_20160624_七侠镇莫尛貝
- Qt tcp socket编程
- 数据库select的几个特殊用法
- 安卓各种权限大全
- HTTP状态码大全
- mysql强制使用索引与不使用索引
- Ubantu 配置Samba实现文件共享
- Builder模式详解--设计模式(5)
- OpenGLES—法线贴图
- 线性表之顺序表