TCP 客户端编程

1.Qt中TCP客户端编程

  • 对Qt编程而言,网络只是数据传输的通道
  • Qt提供了QTcpSocket类(封装了TCP协议细节);
  • 将QTcpSocket的对象当做黑盒使用,进行数据首发。

1.1QTcpSocket类的继承

1.2QTcpSocket的使用

  1. 连接服务器主机(connectToHost())
  2. 发送数据/接受数据(write()/read())
  3. 关闭连接(close())

1.3QTcpSocket的注意事项

  • 默认情况下,QTcpSocket使用异步编程的方式
    • 操作完成后立即返回(返回只代表的操作开始,不代表操作的结果,类似C语言中的回调函数以及Qt中的信号和槽机制)
    • 通过发送信号的方式返回操作的结果

2.QTcpSocket同步编程

2.1QTcpSocket提供辅助函数可完成同步编程的方式(返回值代表返回结果,平时编程使用的大多是同步编程的方式)

- waitForConnected()/waitForDisconnected()
- waitForBytesWritten()/waitForReadyRead()

2.2QTcpSocket同步编程流程

调用完功能函数(如connectToHost)立刻调用对应的同步辅助函数即实现同步编程

2.3QTcpSocket同步编程代码

代码运行时需启动socket的服务程序模拟tcp服务端

#include "clientdemo.h"
#include <QtGui/QApplication>
#include <QTcpSocket>
#include <QDebug>

void SyncClientDemo()
{
	QTcpSocket client;
	char buf[256] = {0};

	client.connectToHost("127.0.0.1", 8080);

	qDebug() << "Connected:" << client.waitForConnected();

	qDebug() << "Send Bytes:" << client.write("D.T.Software");

	qDebug() << "Send Status:" << client.waitForBytesWritten();

	qDebug() << "Data Available:" << client.waitForReadyRead();

	qDebug() << "Received Bytes:" << client.read(buf, sizeof(buf)-1);

	qDebug() << "Received Data:" << buf;

	client.close();

	// client.waitForDisconnected();
}

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	SyncClientDemo();
	//ClientDemo w;
	//w.show();
	return a.exec();
}

结果

3.QTcpSocket异步编程

3.1 QTcpSocket的异步编程

  • QTcpSocket的对象通过发送信号的方式返回操作结果
  • 可以在程序中将对应的信号连接到槽函数,获取结果
  • 在GUI应用程序中通常使用QTcpSocket的异步编程方式

3.2QTcpSocket中的关键信号

  • connected():成功连接远端主机
  • disconnected:远程主机断开连接
  • readyRead():远端主机数据到达本机
  • bytesWritten(qint64):数据成功发送至系统(OS)

3.3编程实践

clientdemo.h

#ifndef CLIENTDEMO_H
#define CLIENTDEMO_H

#include <QObject>
//#include "ui_clientdemo.h"
#include <QTcpSocket>

class ClientDemo : public QObject
{
	Q_OBJECT

		QTcpSocket m_client;
protected slots:
	void onConnected();
	void onDisconnected();
	void onDataReady();
	void onBytesWritten(qint64 bytes);

public:
	qint64 send(const char* data, int len);
	qint64 available();//得到到达本机的数据长度
	ClientDemo(QObject *parent = NULL);
	void connectToHost(QString ip,int port);
    void close();
	~ClientDemo();

private:
//	Ui::ClientDemoClass ui;
};

#endif // CLIENTDEMO_H


clientdemo.cpp

#include "clientdemo.h"
#include <QDebug>

ClientDemo::ClientDemo(QObject *parent): QObject(parent)
{
	//ui.setupUi(this);

	connect(&m_client, SIGNAL(connected()), this, SLOT(onConnected()) );
	connect(&m_client, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
	connect(&m_client, SIGNAL(readyRead()), this, SLOT(onDataReady()));
	connect(&m_client, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));

}
void ClientDemo::onConnected()
{
	qDebug() << "onConnected";
	qDebug() << "Local Address:" ;//<< m_client.localAddress();
	qDebug() << "Local Port:" << m_client.localPort();
}

void ClientDemo::onDisconnected()
{
	 qDebug() << "onDisconnected";
}


void ClientDemo::onDataReady()
{
	  char buf[256] =  {0};
	  qDebug() << "onDataReady:" << m_client.read(buf, sizeof(buf)-1);
	  qDebug() << "Data:" << buf;
}

void ClientDemo::onBytesWritten(qint64 bytes)
{
	qDebug() << "onBytesWritten:" << bytes;
}

void ClientDemo::connectToHost(QString ip,int port)
{
	m_client.connectToHost(ip, port);
}

qint64 ClientDemo::send(const char* data, int len)
{
	 return m_client.write(data, len);
}

qint64 ClientDemo::available()
{
    return m_client.bytesAvailable();
}

void ClientDemo::close()
{
	m_client.close();
}

ClientDemo::~ClientDemo()
{
	
}

main.cpp

#include "clientdemo.h"
#include <QtGui/QApplication>
#include <QTcpSocket>
#include <QDebug>

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	//SyncClientDemo();
	ClientDemo w;
	w.connectToHost("127.0.0.1",8080);
	char buf[]="abc";
	w.send(buf,sizeof(buf)-1);
	//w.show();
	return a.exec();
}

结果

4.小结

  • Qt提供了QTcpSocket类,其对象可用于收发TCP数据
  • QTcpSocket默认使用异步编程方式
  • QTcpSocket提供辅助函数用于完成同步编程的方式
  • GUI应用程序通常使用QTcpSocket的异步编程方式
原文地址:https://www.cnblogs.com/zhaobinyouth/p/11568321.html