如何在QTcpServer使用的套接字上设置SO_REUSEADDR?

2023-12-19

我一直使用 QTcpServer 子类作为 http 服务器,但现在我需要重用服务器端口。

我尝试过设置ShareAddress | ReuseAddressHint在 QTcpSocket 中,它似乎有效,因为同一个端口可以绑定两次。但我没有找到从现有 QTcpServer 对象获取 QTcpSocket 对象的方法。

我也用过socketDescriptor()获取本机套接字,因为我想使用linux C方式setsockopt,但我不知道如何使用linux C代码和Qt代码一起设置套接字选项。(到目前为止我一直遵循Qt风格。)

我在ubuntu和Qt5.4上。我被困住了... 任何帮助,将不胜感激。提前致谢。


Because SO_REUSEPORT http://man7.org/linux/man-pages/man7/socket.7.html之前需要设置bind/listen被调用时,您需要首先创建描述符,设置所有需要的标志,绑定,监听并将描述符转发到QTcp服务器 http://doc.qt.io/qt-5/qtcpserver.html以供将来使用。

这是一个示例,它将在任何接口上侦听端口 9999

mytcpserver.h:

#ifndef MYTCPSERVER_H
#define MYTCPSERVER_H

#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>

class MyTcpServer : public QObject
{
    Q_OBJECT
public:
    explicit MyTcpServer(QObject *parent = 0);

public slots:
    void newConnection();

private:
    QTcpServer *server;
};

#endif // MYTCPSERVER_H

mytcpserver.cpp:

#include "mytcpserver.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

MyTcpServer::MyTcpServer(QObject *parent):QObject(parent)
{
    this->server = new QTcpServer(this);
    connect(server, &QTcpServer::newConnection, this, &MyTcpServer::newConnection);

    // open server and listen on given port
    int sockfd = 0;
    struct sockaddr_in serv_addr;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0)
    {
        qDebug() << "ERROR: IoT Omega Daemon can't open socket";
        exit(EXIT_FAILURE);
    }

    int flag = 1;
    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int)) == -1)
    {
        qDebug() << "ERROR: Can't set SO_REUSEADDR";
        exit(EXIT_FAILURE);
    }

    //set Address,IFace, Port...
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(9999);


    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(sockaddr_in)) < 0)
    {
        qDebug() << "ERROR: can't bind socket";
        exit(EXIT_FAILURE);
    }

    if(listen(sockfd,SOMAXCONN) < 0)
    {
        qDebug() << "ERROR: can't listen on port";
        exit(EXIT_FAILURE);
    }

    //forward our descriptor with SO_REUSEPORT to QTcpServer member
    server->setSocketDescriptor(sockfd);
}

void MyTcpServer::newConnection()
{
    qDebug() << "NEW CONNECTION " << __LINE__;

    QTcpSocket * socket = server->nextPendingConnection();

    socket->write("Hello client\r\n");
    socket->flush();
    socket->waitForBytesWritten(3000);

    socket->close();
}

也许您想进一步优化套接字的使用?例如设置SO_LINGER超时为零,以避免大量连接占用时间的等待状态?也许你不需要等待ACK(TCP_NODELAY)?

那么你的 newConnection 函数可以如下所示:

void MyTcpServer::newConnection()
{
    qDebug() << "NEW CONNECTION " << __LINE__;

    QTcpSocket * socket = server->nextPendingConnection();
    int flag = 1;
    struct linger l = {1,0};

    if(setsockopt(socket->socketDescriptor(), SOL_SOCKET, SO_REUSEADDR, (const char *)&flag, sizeof(int)) < 0)
    {
        qDebug() << "ERROR: Can't set SO_REUSEADDR";
    }

    if(setsockopt(socket->socketDescriptor(), IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)) < 0)
    {
        qDebug() << "ERROR: can't fork set TCP_NODELAY";
    }

    socket->write("Hello client\r\n");
    socket->flush();
    socket->waitForBytesWritten(3000);

    if(setsockopt(socket->socketDescriptor(), SOL_SOCKET, SO_LINGER, (const char *)&l,sizeof(l)) < 0)
    {
        qDebug() << "ERROR: Can't set SO_LINGER";
    }

    socket->close();
}

这将完成工作并释放所有已使用的套接字资源,以便之后可以立即重用它们。对于重负载微服务器等很有用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在QTcpServer使用的套接字上设置SO_REUSEADDR? 的相关文章

  • QMutex 是否需要是静态的,以便此类实例的其他线程调用知道暂停其操作?

    从多个线程调用以下附加函数 我不希望数据重写附加 因为计数器尚未增加 除了当前使用 Append 的线程之外 这是否会挂起所有进入的线程 或者其他线程会继续运行而不追加数据吗 互斥锁是否需要是 静态 的 或者每个实例都知道要暂停操作吗 如果
  • 如何在QT上暂停和重新启动Qtimer

    我有 Ubuntu 我正在使用 IDEQT on C 我将暂停和恢复计时器 例如 void Ordonnancer les taches on pushButton clicked connect dataTimer SIGNAL time
  • 使用 CMake 编译时更改头文件位置会导致缺少 vtable 错误

    对于一个大型 C 项目 我需要从 qmake 过渡到 CMake 但是在处理一个玩具示例时 我遇到了一些我不理解的行为 示例代码具有单个头文件 当该头文件移动到子目录中时 我收到 MainWindow 类缺少 vtable 的错误 CMak
  • SO_BINDTODEVICE Linux 套接字选项的问题

    我有一台带有两个网卡的电脑 一 eth0 用于 LAN 互联网 另一个用于与一个微控制器设备进行 UDP 通信 微控制器有一个 IP 192 168 7 2 和一个 MAC 地址 第二个电脑网络适配器 eth1 有 192 168 7 1
  • SO_REUSEPORT 可以在 Unix 域套接字上使用吗?

    Linux 内核 gt 3 9 允许通过设置在内核负载平衡的进程之间共享套接字SO REUSEPORT http lwn net Articles 542629 http lwn net Articles 542629 这如何用于类型的套接
  • QMainWindow 上的 Qt 布局

    我设计了一个QMainWindow with QtCreator s设计师 它由默认的中央小部件 aQWidget 其中包含一个QVBoxLayout以及其中的所有其他小部件 现在我想要的一切就是QVBoxLayout自动占据整个中央小部件
  • 将 jstring 转换为 QString

    我正在调用一个返回字符串的 Java 函数 QAndroidJniObject obj QAndroidJniObject callStaticObjectMethod
  • PHP Socket Java 消息交换

    我正在尝试在 PHP 页面和正在运行的 Java 服务器之间进行通信 只是通过套接字进行简单的字符串交换 这是我处理连接的线程的 Java 代码 InputStream in clientSocket getInputStream Buff
  • QTableView 并双击一个单元格

    我正在开发测试用例编辑器 该编辑器包含 USART 传输和接收数据包格式 编辑器是一个表格视图 发送和接收数据包的长度为八个字节 例如 0x01 0x02 0x03 0x08 它在我的第五和第六栏中 现在 我希望此列中的单元格为只读 但是当
  • Mac OS X 上的 Qt 字体系列和样式

    我有一个基于 Qt PyQt 的 GUI 应用程序 在 Mac OS X 和其他平台 上运行 它允许用户选择字体并具有粗体和斜体选项的复选框 在更新到新的基于 Cocoa 的 Qt 时 用户发现QFontComboBox不再显示不同的字体样
  • 在本地主机上使用相同的 IP 和端口创建套接字

    我在 Linux 上看到奇怪的行为 我看到远程端和本地端都显示相同的 IP 和端口组合 以下是 netstat 输出 netstat anp 网络统计grep 6102 tcp 0 0 139 185 44 123 61020 0 0 0
  • 如何在Android中使用QML - QWebView

    我想在 Android 中部署一个 YouTube 应用程序 但它只能在我的电脑上运行 在安卓上不起作用 它不加载任何视频 问题仅出在 QWebView 上 我使用了与此类似的代码 http doc qt io archives qt 5
  • Java 客户端到服务器未知来源

    我有一个简单的乒乓球游戏 需要通过网络工作 服务器将创建一个带有球和 2 个球棒位置的游戏 当客户端连接到服务器时 服务器将创建一个名为 PongPlayerThread 的新类 它将处理客户端到服务器的输入和输出流 我的服务器工作100
  • Qt QML 数据模型似乎不适用于 C++

    我一直在使用中的示例http doc qt digia com 4 7 qdeclarativemodels html http doc qt digia com 4 7 qdeclarativemodels html这是 QML 声明性数
  • 将一个整数从 C 客户端发送到 Java 服务器

    我使用此代码将一个整数从我的 Java 客户端发送到我的 Java 服务器 int n rand nextInt 50 1 DataOutputStream dos new DataOutputStream socket getOutput
  • 使用套接字和 AsyncTask 强制关闭

    堆栈的人们大家好 请参阅下面我的班级代码和我的 LogCat 尝试连接时我受到强力关闭 如果有人能帮助我找出原因 我将不胜感激 基本上代码的作用是 从意图中获取 IP 地址 连接到端口 32 的 IP 然后发送一个命令 等待响应并发送另一个
  • QTabWidget 选项卡在垂直方向,但文本在水平方向

    我正在尝试用 C Qt 制作一个带有这样的侧边栏的应用程序 但是当将 QTabWidget 方向设置为西时 它会使文本垂直 如何让文本位于左侧 但水平对齐 PS 我不需要图标 提前致谢 您可以使用QListWidget http doc q
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • Qt 支持 Windows 蓝牙 API 吗?

    谁能告诉我 Qt 是否支持 Windows 蓝牙 API 如果是这样 您能否分享一些有关如何使用它的信息 自上次答复以来 这个问题的答案发生了一些变化 Qt 5 2 版为 Linux BlueZ 和 BlackBerry 设备实现了蓝牙 A
  • 为什么 QT 设计器重新调整大小或不允许我缩小或展开小部件或按钮?

    很多时候 在使用 QT 设计器时 我发现自己需要通过缩小或扩展来调整事物的大小 每当我尝试这样做时 程序都不允许我这样做 而只是恢复到将对象放置在窗口中时给我的原始默认大小 无论我的布局如何 为什么要这样做 是否有可能改变这一点 以便我可以

随机推荐