TCP连接时客户端和服务器做的(Linux里)
服务器
- socket
- bind
- listen
- accept
- send/recv
- close
客户端
- socket
- connect
- recv/send
- close
函数详见:
工程文件修改
使用qmake构建系统时,与网络 和数据库有关的项目在工程文件.pro中加上network,例如:
cpp
QT += core gui network
若用CMake构建系统,用find_package找到 Qt 对应的模块(如网络模块 Network
、数据库模块 Sql
)
cpp
# Qt6 需明确指定COMPONENTS,Qt5语法类似但模块名可能略有差异
find_package(Qt6 COMPONENTS Core Network Sql REQUIRED)
要使用的头文件
套接字的头文件:<QTcpSocket>
IP地址:<QHostAddress>
服务器
- 创建QTcpServer对象//服务器
- 监听listen:ip和port
- 连接信号和槽connect(客户端连接后server对象 发出的信号)
- 槽函数处理信号:建立Tcp连接
UI
服务器接收显示客户端的IP和端口。

头文件
在 Qt 中,服务器的监听 socket 被 QTcpServer 类封装,开发者无需直接调用底层
socket()
函数创建,而是通过QTcpServer
对象间接使用。
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QTcpServer>
#include<QTcpsocket>
#define PORT 8000
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
void newClientHandler();//连接新客户端
private:
Ui::Widget *ui;
QTcpServer *server;
};
#endif // WIDGET_H
cpp文件
建立TCP连接:
QTcpServer
调用 listen()
开始监听端口后,客户端通过 QTcpSocket::connectToHost()
发起连接请求时:
- 服务器会触发 **newConnection()**信号(表示有新连接到达)。
- 此时可调用 nextPendingConnection() 获取这个新连接对应的
QTcpSocket
指针。
获取客户端地址: socket->peerAddress(); 返回**QHostAddress
** 类型对象
获取客户端端口号: socket->peerPort(); 返回整数类型(quint16
,无符号 16 位整数)
cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
server = new QTcpServer;
//监听IP和端口
server->listen(QHostAddress::AnyIPv4,PORT);
//客户端发起连接,server发出信号:newConnection
connect(server,&QTcpServer::newConnection,this,&Widget::newClientHandler);
}
Widget::~Widget()
{
delete ui;
}
//处理客户端
void Widget::newClientHandler()
{
//建立TCP连接,返回地址
QTcpSocket *socket = server->nextPendingConnection();
ui->IPlineEdit->setText(socket->peerAddress().toString());
ui->portlineEdit->setText(QString::number(socket->peerPort()));
}
客户端
创建一个QTcpsocket对象,connectToHost连接服务器
socket 套接字是接口 ,"IP 地址 + 端口号" 标识了一个套接字端点 ,两个套接字(客户端和服务器)通过网络协议 (如 TCP、UDP)建立连接,实现数据收发。
常用信号:连接:connected;断开:disconnected
UI
填写要连接的服务器的ip地址和端口号,选择连接或断开(取消)。

头文件
创建一个socket对象
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QTcpSocket>
#include<QHostAddress>
#include<QMessageBox>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_cancelButton_clicked();
void on_connectButton_clicked();
private:
Ui::Widget *ui;
QTcpSocket *socket;
};
#endif // WIDGET_H
cpp文件
socket对象要new
连接服务器:
socket->connectToHost(QHostAddress(IP),port.toShort());
按按钮的槽函数里面包括(处理连接和断开信号的connect,这里的处理函数直接用lambda表达式写了)
cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
socket = new QTcpSocket;//创建socket对象
}
Widget::~Widget()
{
delete ui;
}
//按取消按钮的处理
void Widget::on_cancelButton_clicked()
{
this->close();//关闭
}
//得到按连接按钮信号的处理
void Widget::on_connectButton_clicked()
{
//获取ip地址和端口号
QString IP = ui->IPEdit->text();
QString port = ui->portEdit->text();
//连接服务器
socket->connectToHost(QHostAddress(IP),port.toShort());
//连接成功会有一个socket发出的connected的信号
connect(socket,&QTcpSocket::connected,[this]()
{
QMessageBox::information(this,"连接提示","连接服务器成功");
});
//连接断开socket发出信号
connect(socket,&QTcpSocket::disconnected,[this]()
{
QMessageBox::warning(this,"连接提示","连接异常,网络断开");
});
}
连接测试
127这个ip是本地环回测试地址。
指定服务器监听8000这个端口(服务器代码头文件中的#define PORT 8000)。
