QT的TCP应用-传输图片

2023-05-16

1.server.h

#ifndef SERVER_H
#define SERVER_H

#include <QMainWindow>
#include<QLabel>
#include<QtNetwork/QHostInfo>
#include<QtNetwork/QTcpServer>
#include<QtNetwork/QTcpSocket>
#include<QFile>

namespace Ui {
class Server;
}

class Server : public QMainWindow
{
    Q_OBJECT
private:
    QLabel *LabListen;
    QLabel *LabSocketState;
    QTcpServer *tcpServer;
    QTcpSocket *tcpSocket;
    QString getlocalIP();
private:  //file
    QTcpServer *fileServer;
    QTcpSocket *fileSocket;
    qint64 totalBytes;
    qint64 bytesReceived;
    qint64 bytestoWrite;
    qint64 bytesWritten;
    qint64 filenameSize;
    QString filename;
    QString m_imgDirPath;
    ///每次发送数据大小
    qint64 perDataSize;
    QFile *localFile;
    本地缓冲区
    QByteArray inBlock;
    QByteArray outBlock;

    void initSocket();
    void initFileSocket();

private slots:
    void onNewConnection();
    void onSocketStateChange(QAbstractSocket::SocketState socketState);
    void onClientConnected();
    void onClientDisconnected();
    void onSocketReadyRead();

    void acceptFileConnection();
    void updateFileProgress();
    void displayError(QAbstractSocket::SocketError socketError);
    void updateFileProgress(qint64);

    //void on_openImgButton_clicked(); //浏览按钮-点击槽函数
    void on_imgListWidget_clicked(const QModelIndex &index);  //图片列表-点击槽函数

protected:
    void closeEvent(QCloseEvent *event);

private slots:
   void on_acHostInfo_triggered();
   void on_actStart_triggered();
   void on_actStop_triggered();
   void on_btnSendMsg_clicked();
   void on_btnSaveDir_clicked();
   void on_btnSelectFile_clicked();
   void on_btnSendFile_clicked();
   void Auto_get_mac_IP();
   void on_choose_image_pushButton_clicked();

   void on_closeimage_pushButton_clicked();

   void on_actClear_triggered();

public:
    explicit Server(QWidget *parent = 0);
    ~Server();
   //QMediaPlayer *player1,*player2;

private:
    Ui::Server *ui;
};

#endif // SERVER_H

2、main.c

#include "server.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Server w;
    w.show();

    return a.exec();
}

3、server.cpp

#include "server.h"
#include "ui_server.h"
#include<QFileDialog>
#include <QMessageBox>
#include <QMainWindow>
#include <QMovie>
#include <QDebug>
#include <QDateTime>
#include <QSettings>
#include <qnetworkinterface.h>

QString Server::getlocalIP()
{
    QString hostName=QHostInfo::localHostName();
    QHostInfo hostInfo=QHostInfo::fromName(hostName);

    QList<QHostAddress> addList=hostInfo.addresses();
    if(!addList.isEmpty())
        for(int i=0;i<addList.count();i++)
        {
            QHostAddress localIP =addList.at(i);
            if(localIP.protocol()==QAbstractSocket::IPv4Protocol)
                return localIP.toString();
        }
    return "";
}

Server::Server(QWidget *parent) :QMainWindow(parent), ui(new Ui::Server)
{
    ui->setupUi(this);
    this->setWindowTitle("Tcp Server");
    initSocket();
    initFileSocket();
    Auto_get_mac_IP();
    //设置指定背景色
    ui->image_label->setStyleSheet("background-color:rgb(222, 222, 222);");//图片显示区域颜色
    ui->imgListWidget->setStyleSheet("background-color:rgb(222, 222, 222);");//接收名字区域设置
    ui->plainTextEdit->setStyleSheet("background-color:rgb(222, 222, 222);");//信息显示区域背景颜色

    ui->fg_label->setStyleSheet("QLabel{background-color:rgb(143, 0, 0);}");//信息提示去颜色
    ui->fg_label->setStyleSheet("background-color:rgb(143, 0, 0);font-size:18px;color:white");

    ui->img_label->setStyleSheet("QLabel{background-color:rgb(143, 0, 0);}");//信息提示去颜色
    ui->img_label->setStyleSheet("background-color:rgb(143, 0, 0);font-size:18px;color:white");

    ui->information_prompt_area_laber->setStyleSheet("background-color:rgb(143, 0, 0);font-size:18px;color:white");
    ui->Picture_display_area_label->setStyleSheet("background-color:rgb(143, 0, 0);font-size:18px;color:white");//图片显示区域背景颜色
}
void Server::Auto_get_mac_IP()//放到自动程序中,开机获取本机地址
{

//通过QNetworkInterface类来获取本机的IP地址和网络接口信息。
 QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();//获取所有网络接口的列表
  //获取所有网络接口的列表
 foreach(QNetworkInterface interface,list)
    {  //遍历每一个网络接口
     qDebug() << "Device: "<<interface.name();  //设备名
     //硬件地址
     qDebug() << "HardwareAddress: "<<interface.hardwareAddress();

/**********************************************************************************************/
/*
 * ubuntu下获取ip地址  start
 */
/**********************************************************************************************/
if(interface.name()=="enp2s0"|interface.name()=="ethernet_32774")//我的ubuntu端口是enp2s0,windosethernet_32774 是你的需要根据自己的来判断
    {
   QList<QNetworkAddressEntry> entryList = interface.addressEntries();
          //获取IP地址条目列表,每个条目中包含一个IP地址,一个子网掩码和一个广播地址
     foreach(QNetworkAddressEntry entry,entryList)
      {//遍历每一个IP地址条目

        if( entry.ip().toString().size() < 16)//区分IPV6和IPV4
       {
        qDebug()<<"IP Address: "<<entry.ip().toString();
                    //IP地址
        qDebug()<<"Netmask: "  <<entry.netmask().toString();
                    //子网掩码
        qDebug()<<"Broadcast: "<<entry.broadcast().toString();
                    //广播地址
        ui->editIP->clear();//
        ui->editIP->setText(QString (entry.ip().toString()));
        }
       }
    }
/**********************************************************************************************/
/*
* ubuntu下获取ip地址  end
*/
/**********************************************************************************************/
 }
}
void Server::on_acHostInfo_triggered()
{
   Auto_get_mac_IP();//按键 再次刷新ip地址
}

void Server::initSocket()
{
    LabListen=new QLabel("监听状态:");
    LabListen->setMinimumWidth(150);
    ui->statusBar->addWidget(LabListen);
    LabSocketState=new QLabel("Socket状态:");//
    LabSocketState->setMinimumWidth(200);
    ui->statusBar->addWidget(LabSocketState);

    tcpServer=new QTcpServer(this);
    connect(tcpServer,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
}

void Server::initFileSocket()
{

     文件传送相关变量初始化
    perDataSize = 64*1024;
    totalBytes = 0;
    bytestoWrite = 0;
    bytesWritten = 0;
    bytesReceived = 0;
    filenameSize = 0;
    ///文件传送套接字
    fileSocket = new QTcpSocket(this);
    fileServer = new QTcpServer(this);

    quint16 port=ui->spinPort->value()+1;//端口
    qDebug()<<"initFileSocket"<<port;

    fileServer->listen(QHostAddress::Any,ui->spinPort->value()+1);
    connect(fileServer,SIGNAL(newConnection()),this,SLOT(acceptFileConnection()));

}
Server::~Server()
{
    delete ui;
    delete tcpServer;
    delete fileServer;
}

void Server::on_actStart_triggered()
{
    //从界面上读取ip和端口
    const QString address_IP=ui->editIP->text();//IP地址
          quint16 port=ui->spinPort->value();//端口
   //可以使用 QHostAddress::Any 监听所有地址的对应端口
    const QHostAddress address=(address_IP=="Any")?QHostAddress::Any:QHostAddress(address_IP);
    tcpServer->listen(address,port);//

    tcpServer->listen(QHostAddress::LocalHost,port);
    ui->plainTextEdit->appendPlainText("**开始监听...");
    ui->plainTextEdit->appendPlainText("**服务器地址:"+tcpServer->serverAddress().toString());
    ui->plainTextEdit->appendPlainText("**服务器端口:"+QString::number(tcpServer->serverPort()));
    ui->actStart->setEnabled(false);
    ui->actStop->setEnabled(true);
    LabListen->setText("监听状态:正在监听");
}
void Server::on_actStop_triggered()
{//停止监听
    if (tcpServer->isListening()) //tcpServer正在监听
    {
        tcpServer->close();//停止监听
        ui->actStart->setEnabled(true);
        ui->actStop->setEnabled(false);
        LabListen->setText("监听状态:已停止监听");
    }
}

void Server::onNewConnection()
{
    ui->plainTextEdit->appendPlainText("有新连接");
    tcpSocket = tcpServer->nextPendingConnection(); //创建socket
    connect(tcpSocket, SIGNAL(connected()),this, SLOT(onClientConnected()));//
    connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
    connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this,SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
    onSocketStateChange(tcpSocket->state());

    //连接信号与槽
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));

     qDebug()<<"Client connected success.";
}
void Server::onSocketStateChange(QAbstractSocket::SocketState socketState)
{//socket状态变化时
    switch(socketState)
    {
    case QAbstractSocket::UnconnectedState:
        LabSocketState->setText("scoket状态:UnconnectedState");
        break;
    case QAbstractSocket::HostLookupState:
        LabSocketState->setText("scoket状态:HostLookupState");
        break;
    case QAbstractSocket::ConnectingState:
        LabSocketState->setText("scoket状态:ConnectingState");
        break;
    case QAbstractSocket::ConnectedState:
        LabSocketState->setText("scoket状态:ConnectedState");
        break;
    case QAbstractSocket::BoundState:
        LabSocketState->setText("scoket状态:BoundState");
        break;
    case QAbstractSocket::ClosingState:
        LabSocketState->setText("scoket状态:ClosingState");
        break;
    case QAbstractSocket::ListeningState:
        LabSocketState->setText("scoket状态:ListeningState");
    }
}

void Server::onClientConnected()
{//客户端接入时
    ui->plainTextEdit->appendPlainText("**client socket connected");
    ui->plainTextEdit->appendPlainText("**peer address:"+tcpSocket->peerAddress().toString());
    ui->plainTextEdit->appendPlainText("**peer port:"+QString::number(tcpSocket->peerPort()));
}

void Server::onClientDisconnected()
{//客户端断开连接时
    ui->plainTextEdit->appendPlainText("**client socket disconnected");
    tcpSocket->deleteLater();
   // deleteLater();
}

void Server::onSocketReadyRead()
{
    ui->plainTextEdit->appendPlainText("[in] "+tcpSocket->readAll());

//    ui->image_label->setPixmap(QPixmap(QString::fromLocal8Bit("E:\QT\TCP_Client_Server\\1.png"))); // 在imgLabel标签上显示图片
//    ui->image_label->setScaledContents(true);
//    ui->image_label->show();
}

void Server::on_btnSendMsg_clicked()
{
    QString  msg=ui->editMsg->text();
    ui->plainTextEdit->appendPlainText("[out] "+msg);
    ui->editMsg->clear();
    ui->editMsg->setFocus();

    QByteArray  str=msg.toUtf8();
    //str.append('\n');//添加一个换行符
    tcpSocket->write(str);
}

void Server::closeEvent(QCloseEvent *event)
{//关闭窗口时停止监听
    if (tcpServer->isListening())
        tcpServer->close();//停止网络监听
    if (fileServer->isListening())
        fileServer->close();//停止网络监听
    event->accept();
}

void Server::acceptFileConnection()
{

    bytesWritten = 0;
    ///每次发送数据大小为64kb
    perDataSize = 64*1024;
    fileSocket =fileServer->nextPendingConnection();
    ///接受文件
    readyRead()当网络套接字上有新的网络数据有效负载时
    connect(fileSocket,SIGNAL(readyRead()),this,SLOT(updateFileProgress()));
    connect(fileSocket,SIGNAL(bytesWritten(qint64)),this,SLOT(updateFileProgress(qint64)));

     处理异常
    connect(fileSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(displayError(QAbstractSocket::SocketError)));

}

/**
 * 接收文件进度
 * @brief Server::updateFileProgress
 */
void Server::updateFileProgress()
{
    QDataStream inFile(fileSocket);
    inFile.setVersion(QDataStream::Qt_5_6);
    ui->plainTextEdit->appendPlainText("updateFileProgress");

    ///如果接收到的数据小于16个字节,保存到来的文件头结构
    if(bytesReceived <= sizeof(qint64)*2)
    {

        QByteArray bytes = NULL;
        while(this->fileSocket->waitForReadyRead(100))
        {
            qDebug()<<"Data receiving...";
            bytes.append(this->fileSocket->readAll());
        }

        //Send Back Data to Client
         if(this->fileSocket->isWritable())
         {
                //结尾中的'\n'表示数据发送完毕
//                QString sendData = "ok\n" ;
//                QByteArray  strs=sendData.toUtf8();
//                this->fileSocket->write(strs);
          }
          else
          {
              qDebug()<<"Cannot send back data to Client.";
          }


        QPixmap pixmap;
        pixmap.loadFromData(bytes);
        //显示到GUI中
        int with = ui->image_label->width();
        int height = ui->image_label->height();

        //QPixmap fitpixmap = pixmap.scaled(with, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);  // 饱满填充
         QPixmap fitpixmap = pixmap.scaled(with, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);  // 按比例缩放
         //ui->image_label->setScaledContents(false);    //根据label大小缩放图片
        ui->image_label->setPixmap(fitpixmap);

        //时间保存文件名
        QDateTime datetime;
        QString timestr = datetime.currentDateTime().toString("yyyyMMddHHmmss");

        //保存路径
         filename =  ui->editSaveDir->text()+"/"+timestr+".png";
         qDebug()<<"filename"<<filename;
         localFile = new QFile(filename);
         if(!localFile->open(QFile::WriteOnly))
         {
             ui->plainTextEdit->appendPlainText("Server::open file error!");
             return;
         }

         //保存文件
         localFile->write(bytes);
         bytes.resize(0);
    }
    ///如果接收到的数据小于16个字节,保存到来的文件头结构
    if(bytesReceived <= sizeof(qint64)*2)
    {

        if((fileSocket->bytesAvailable()>=(sizeof(qint64))*2) && (filenameSize==0))
        {
             接收数据总大小信息和文件名大小信息
            inFile>>totalBytes>>filenameSize;
            bytesReceived += sizeof(qint64)*2;
            qDebug()<<"filenameSize success."<< filenameSize;
        }
        if((fileSocket->bytesAvailable()>=filenameSize) && (filenameSize != 0))
        {
            inFile>>filename;
            bytesReceived += filenameSize;
            接收的文件放在指定目录下
            filename = ui->editSaveDir->text()+"/"+filename;
            localFile = new QFile(filename);
            if(!localFile->open(QFile::WriteOnly))
            {
                ui->plainTextEdit->appendPlainText("Server::open file error!");
                return;
            }
        }
        else
            return;
    }
    /如果接收的数据小于总数据,则写入文件
    if(bytesReceived < totalBytes)
    {
        bytesReceived += fileSocket->bytesAvailable();
        inBlock = fileSocket->readAll();
        localFile->write(inBlock);
        inBlock.resize(0);
    }
    更新进度条显示
    this->ui->progressBarRec->setMaximum(totalBytes);
    this->ui->progressBarRec->setValue(bytesReceived);
    数据接收完成时
    if(bytesReceived == totalBytes)
    {
        this->ui->plainTextEdit->appendPlainText("Receive file successfully!");
        bytesReceived = 0;
        totalBytes = 0;
        filenameSize = 0;
        localFile->close();
        //fileSocket->close();
    }
}
void Server::updateFileProgress(qint64 numBytes)
{ 已经发送的数据大小
    bytesWritten += (int)numBytes;
    如果已经发送了数据
    if(bytestoWrite > 0)
    {
        outBlock = localFile->read(qMin(bytestoWrite,perDataSize));
        ///发送完一次数据后还剩余数据的大小
        bytestoWrite -= ((int)fileSocket->write(outBlock));
        ///清空发送缓冲区
        outBlock.resize(0);
    }
    else
        localFile->close();
    更新进度条
    this->ui->progressBarSend->setMaximum(totalBytes);
    this->ui->progressBarSend->setValue(bytesWritten);

    如果发送完毕
    qDebug()<<"bytesWritten"<<bytesWritten<<"--"<<"totalBytes"<<totalBytes;
    if(bytesWritten == totalBytes)
    {
       bytesWritten=0;totalBytes=0;
       localFile->close();
      // fileSocket->close();
       qDebug()<<ui->progressBarRec->value()<<"value";
       qDebug()<<ui->progressBarRec->maximum()<<"maximum";
    }
}
/**
 * @brief Server::getImage base64 转图片
 * @param data
 * @return
 */
//QImage Server::getImage(const QString &data)
//{
//    QByteArray imageData = QByteArray::fromBase64(data.toLatin1());
//    QImage image;
//    image.loadFromData(imageData);
//    return image;
//}

void Server::displayError(QAbstractSocket::SocketError socketError)
{
    ui->plainTextEdit->appendPlainText(fileSocket->errorString());
    //socket->close();
}

void Server::on_btnSaveDir_clicked()
{
    ui->editSaveDir->setText(QFileDialog::getExistingDirectory(this,"请选择保存路径"));
}
void Server::on_btnSelectFile_clicked()
{
   //  ui->editFile->setText(QFileDialog::getOpenFileName(this,"请选择待发送文件"));
    //???fileSocket->open(QIODevice::WriteOnly);
    ///文件传送进度更新
    //connect(fileSocket,SIGNAL(bytesWritten(qint64)),this,SLOT(updateFileProgress(qint64)));
    filename = QFileDialog::getOpenFileName(this,"Open a file");
    ui->editFile->setText(filename);
}

void Server::on_btnSendFile_clicked()
{

    localFile = new QFile(filename);
    if(!localFile->open(QFile::ReadOnly))
    {
        ui->plainTextEdit->appendPlainText("Client:open file error!");
        return;
    }
    ///获取文件大小
    this->totalBytes = localFile->size();
    QDataStream sendout(&outBlock,QIODevice::WriteOnly);
    sendout.setVersion(QDataStream::Qt_4_8);
    QString currentFileName = filename.right(filename.size()-filename.lastIndexOf('/')-1);

    qDebug()<<sizeof(currentFileName);
    保留总代大小信息空间、文件名大小信息空间、文件名
    sendout<<qint64(0)<<qint64(0)<<currentFileName;
    totalBytes += outBlock.size();
    sendout.device()->seek(0);
    sendout<<totalBytes<<qint64((outBlock.size()-sizeof(qint64)*2));

    bytestoWrite = totalBytes-fileSocket->write(outBlock);
    outBlock.resize(0);
}
/*
void MainWindow::on_openImgButton_clicked()
{
    //m_imgDirPath = QFileDialog::getExistingDirectory(this); // 获取图片所在目录的具体路径
    m_imgDirPath=ui->lineEdit->text();
    QDir dir(m_imgDirPath);

    QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files); // 获取目录下的文件

    QString filePath; // 保存图片图片的绝对路径
    // 在QListWidget中列出目录下的文件
    for(int i=0; i<fileInfoList.count(); i++)
    {
        filePath.clear(); //清除上一次图片路径内容
        filePath.append(m_imgDirPath + "/" + fileInfoList.at(i).fileName()); // 获得图片文件的绝对路径

        if(fileInfoList.at(i).fileName() == "." || fileInfoList.at(i).fileName() == "..") // 跳过这两个隐藏目录
        {
            continue;
        }
        QListWidgetItem *item = new QListWidgetItem(QIcon(filePath), fileInfoList.at(i).fileName()); // 建立图片缩小图标
        ui->imgListWidget->addItem(item); // 把图片缩小图标和名称显示在列表窗口中
    }
}


*/
void Server::on_choose_image_pushButton_clicked()
{
 /*   QString filename;
    QPixmap image_label;
    filename=QFileDialog::getOpenFileName(this,tr("选择图像"),"",tr("Images (*.png *.bmp *.jpg *.tif *.GIF )"));//可打开的文件类型
    if(!filename.isEmpty())
    {
        QImage image(filename);
        ui->image_label->setPixmap(image_label.fromImage(image));// ui->image_label就是label的控件名字
        ui->image_label->setScaledContents(true);
        ui->image_label->show();

    }
*/

    m_imgDirPath=ui->editSaveDir->text();
    QString filter;
    QDir dir(m_imgDirPath);
    QFileInfoList fileInfoList = dir.entryInfoList(); // 获取目录下的文件
    QString filePath; // 保存图片图片的绝对路径
    foreach(QFileInfo fileinfo, fileInfoList )filter = fileinfo.suffix(); //后缀名
    // 在QListWidget中列出目录下的文件


    for(int i=0; i<fileInfoList.count(); i++)
    {
        filePath.clear(); //清除上一次图片路径内容
        filePath.append(m_imgDirPath + "/" + fileInfoList.at(i).fileName()); // 获得图片文件的绝对路径
      if(fileInfoList.at(i).fileName() == "." || fileInfoList.at(i).fileName() == "..") // 跳过这两个隐藏目录
        {
            continue;
        }
        QListWidgetItem *item = new QListWidgetItem(QIcon(filePath), fileInfoList.at(i).fileName()); // 建立图片缩小图标
        ui->imgListWidget->addItem(item); // 把图片缩小图标和名称显示在列表窗口中
    }
        ui->img_label->setText("图片加载完成");
}
//图片列表-点击槽函数
void Server::on_imgListWidget_clicked(const QModelIndex &index)
{
    Q_UNUSED(index);

    QString imgPath = (m_imgDirPath + "/" + ui->imgListWidget->currentItem()->text());

    if(imgPath.endsWith(".gif") || imgPath.endsWith(".Gif")) //判断是否是gif动图
    {

        QMovie *movie =new QMovie(imgPath);
        ui->image_label->setMovie(movie);
        movie->start();
    }
    else
    {
        //显示图片
        int with = ui->image_label->width();
        int height = ui->image_label->height();

        //QPixmap fitpixmap = pixmap.scaled(with, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);  // 饱满填充
         QPixmap fitpixmap = QPixmap(imgPath).scaled(with, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);  // 按比例缩放
         //ui->image_label->setScaledContents(false);    //根据label大小缩放图片
        ui->image_label->setPixmap(fitpixmap);

      // ui->image_label->setPixmap(QPixmap(imgPath)); // 在imgLabel标签上显示图片
    //   ui->image_label->setScaledContents(true);    //根据label大小缩放图片
    }

}
void Server::on_closeimage_pushButton_clicked()
{
    ui->image_label->clear();
    ui->imgListWidget->clear();
    ui->img_label->setText("请加载图片");
}

void Server::on_actClear_triggered()
{
   ui->plainTextEdit->clear();
}

实际效果:
在这里插入图片描述
下载:https://gitee.com/pang_xi_wen/qtq.git

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

QT的TCP应用-传输图片 的相关文章

  • IPv4 允许的最大 TCP/IP 网络端口号是多少?

    可以使用的最大端口号是多少 端口号是一个无符号 16 位整数 即 65535
  • wireshark 和 tcpdump -r:奇怪的 tcp 窗口大小

    我正在使用 tcpdump 捕获 http 流量 并且对 TCP 慢启动以及窗口大小如何增加感兴趣 sudo tcpdump i eth1 w wget tcpdump tcp and port 80 当我使用 Wireshark 查看转储
  • Nodejs TCP连接客户端端口分配

    我使用nodejs在客户端和服务器之间创建了tcp连接 网络模块 https nodejs org api net html 服务器正在侦听已经预定义的端口 并且客户端正在连接到该端口 据我了解客户端的端口是由节点动态分配的 那是对的吗 节
  • TCP 代理:在后端不可用时保持连接

    在 Docker 设置的上下文中 我想使用类似大使的模式来允许某些容器 例如数据库服务器 正常重新启动 而不必重新启动所有依赖的容器 例如 Web 服务器 并且没有错误消息 因为 数据库服务器不可用 因此 我想知道 是否有一个 TCP 代理
  • 通过 TCP 客户端套接字接收数据时出现问题

    我正在尝试用 C 语言编写一个 TCP 客户端程序 客户端将在其中启动 连接到服务器 然后它会发送一些信息 然后监听它收到的信息并做出相应的反应 我遇到麻烦的部分是持续聆听 这是我所拥有的 while 1 numbytes recv soc
  • Socket ReceiveAsync 合并数据包

    我打算通过套接字接收数据包 但由于它们是从发送方以高频率发送的 因此其中许多数据包被打包成一个byte array SocketAsyncEventArgs Buffer然后保存多个数据包 即使它们是单独发送的 使用验证wireshark
  • 在 C# 中通过 TCP 发送 C 结构体

    我正在编写一个程序 通过 TCP 与一台设备的管理界面进行交互 问题是 设备的文档是用C写的 而我写的程序是用C 写的 我的问题是 文档指定 通信基于基于C结构的API缓冲区 再多的谷歌搜索似乎也无法让我找到这个 API 或如何通过 TCP
  • 如何在NodeJS中测试socket.setKeepAlive

    我尝试在NodeJS中测试setKeepAlive 的功能 我在同一本地网络中的不同计算机上运行 Server js 和 client js 然后 我关闭了客户端计算机上的 WiFi 连接 断开互联网连接 15分钟后 仍然没有消息抛出 这是
  • C# - 从客户端检查 TCP/IP 套接字状态

    我想为我的 TCP IP 客户端类提供 CheckConnection 函数 以便我可以检查是否发生了错误 我自己的客户端断开连接 服务器断开连接 服务器卡住等 我有类似的东西 bool isConnectionActive false i
  • 数据包丢失和数据包重复

    我试图找出数据包丢失和数据包重复问题之间的区别 有谁知道 数据包重复 是什么意思 和TCP检测到丢失时重传数据包一样吗 No In TCP 数据包 的传递是可靠的 我认为在这种情况下术语数据应该更好 因为它是面向流的协议 数据包丢失和重复是
  • 两个http请求可以合并在一起吗?如果可以的话,nodeJS服务器如何处理呢?

    昨天我做了一些关于 NodeJS 的演讲 有人问我以下问题 我们知道nodeJS是一个单线程服务器 多个请求是 到达服务器并将所有请求推送到事件循环 如果什么 两个请求同时到达服务器 服务器将如何处理 处理这种情况 我猜到了一个想法并回复如
  • C# Socket.receive连续接收0字节且循环中不阻塞

    我正在尝试用 C 编写一个最简单的多线程 TCP 服务器 它接收来自多个客户端的数据 每次连接新客户端时 都会建立套接字连接 并将套接字作为参数传递给新类函数 之后运行 while 循环并接收数据 直到客户端连接为止 这里的问题是 sock
  • 如何在Linux中打开端口[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我已经安装了 Web 应用程序 该应用程序在 RHEL centOS 上的端口 8080 上运行 我只能通过命令行访问该机器 我尝试从我的
  • AMQP如何克服直接使用TCP的困难?

    AMQP如何克服直接使用TCP发送消息时的困难 或者更具体地说 在发布 订阅场景中 在 AMQP 中 有一个代理 该代理接收消息 然后完成将消息路由到交换器和队列的困难部分 您还可以设置持久队列 即使客户端断开连接 也可以为客户端保存消息
  • 视频流上的 TCP 与 UDP

    我刚从网络编程考试回来 他们问我们的问题之一是 如果您要传输视频 您会使用 TCP 还是 UDP 请解释一下存储视频和实时视频流 对于这个问题 他们只是希望得到一个简短的答案 TCP 用于存储视频 UDP 用于实时视频 但我在回家的路上想到
  • 我应该害怕使用 UDP 进行客户端/服务器广播通话吗?

    我在过去的两天里阅读了每一篇StackOverflow问题和答案 以及googling当然 关于印地TCP and UDP协议 以便决定在我的用户应用程序和 Windows 服务之间的通信方法中应该使用哪一种 从我目前所看到的来看 UDP是
  • 为什么 TCP 段中的 SYN 或 FIN 位会占用序列号空间中​​的一个字节?

    我试图理解这种设计背后的基本原理 我浏览了一些 RFC 但没有发现任何明显的东西 这并不是特别微妙 这样 SYN 和 FIN 位本身就可以被确认 因此如果丢失则可以重新发送 例如 如果连接关闭而没有发送更多数据 那么如果 FIN 没有发送任
  • 为什么 UDP 服务器中只有一个套接字?

    我正在准备考试 发现了这个问题 典型的 UDP 服务器可以使用单个套接字来实现 解释一下为什么 对于 TCP 驱动的服务器 我发现创建了两个套接字 一个用于所有客户端访问服务器 另一个用于每个客户端的特定 套接字 用于服务器和客户端之间的进
  • 建立 TCP 连接边界的正确方法

    我的问题是关于如何正确处理使用 tcp 连接接收的数据 事实上 通过建立 tcp 连接 创建了一个流 假设我想发送一条有开头和结尾的消息 由于数据在流中流动而没有指定任何边界 我如何识别消息的开始和结束 我想在消息的开头和结尾处放置一些特殊
  • 谁在 Mac OS X 上监听给定的 TCP 端口?

    在Linux上 我可以使用netstat pntl grep PORT or fuser n tcp PORT找出哪个进程 PID 正在侦听指定的 TCP 端口 如何在 Mac OS X 上获得相同的信息 在 macOS 上Big Sur然

随机推荐

  • Downloading https://ultralytics.com/assets/Arial.ttf to /data/..../.config/Ultralytics/Arial.ttf

    1 报错 xff1a 缺少字体Arial ttf 2 字体链接 xff1a https ultralytics com assets Arial ttf 3 方法 xff1a 下载该链接的字体 xff0c 然后放到 data config
  • 第四章 Opencv图像色彩空间与通道

    文章目录 1 色彩空间1 1 RGB BGR色彩空间1 2 GRAY色彩空间1 3 HSV色彩空间 2 通道2 1 拆分通道 xff1a 96 split 96 方法1 拆BGR色彩空间图像的通道2 拆HSV色彩空间图像的通道 2 2 合并
  • 第五章 Opencv图像的几何变换

    目录 1 缩放图像1 1 resize 方法 2 翻转图像2 1 flip 方法 3 仿射变换图像3 1 warpAffine 方法3 2 平移3 3 旋转3 4 倾斜 4 透视图像4 1 warpPerspective 方法 几何变换是指
  • pip、conda查看镜像源及更换镜像源

    1 查看已经安装过的镜像源 xff1a conda config show channels 查看配置项channels 2 删除镜像源 xff08 清华镜像源 xff09 xff1a conda config remove channel
  • 生成环境下的所有包

    pip freeze span class token operator gt span requirements span class token punctuation span txt 问题 xff1a 将虚拟环境的安装包导出 xff
  • java核心技术卷I

    第三章 xff1a java的基本程序设计结构 文章目录 第三章 xff1a java的基本程序设计结构3 2 注释3 3 数据类型3 4变量3 4 1初始化变量3 4 2常量 3 5运算符3 5 1数学函数与常量3 5 2数值类型之间的转
  • MOT学习笔记 — 行人检测及行人跟踪数据集总结

    1 行人红外数据集总结 xff08 1 xff09 OSU Thermal Pedestrian Database 下载链接 xff1a http vcipl okstate org pbvs bench Data 01 download
  • 使用k-近邻算法识别手写数字

    本文摘自 机器学习实战 案例 xff0c 对其进行了代码更新与注释 实战介绍 使用k 近邻分类器构造手写识别系统 xff0c 为了简单起见 xff0c 系统只识别0 9 xff0c 需要识别的数字已经使用图形处理软件 xff0c 处理成具有
  • ubuntu16.04下安装并使用小觅双目MYNT EYE 1.x SDK

    1 下载MYNT EYE 1 x SDK压缩包 首先 xff0c 点击进入github官网 xff0c 在右上角的搜索栏中输入mynt xff0c 进入如下界面 xff1a 点击第四个slightech MYNT EYE SDK进入 xff
  • UART通用异步收发传输器

    UART 全称Universal Asynchronous Receiver Transmitter xff0c 通用异步收发传输器 xff0c 是一种串行异步收发协议 又称为串口 xff09 功能是将并行的数据转变为串行的数据发送或者将接
  • C语言如何实现输入特定字符串(单词)作为终止符

    本文章以一个例题来进行讲解 xff08 新手第一次写 xff0c 目的仅是分享自己写代码中想到的一些方法和技巧 xff0c 仍存在很多不足 xff0c 希望能对大家有用 xff09 题目要求 xff1a 有一篇文章 xff0c 共有多行文字
  • kubernetes 教程 笔记

    K8s 安装kub ectl 下载kubectl curl LO 34 https dl k8s io release curl L s https dl k8s io release stable txt bin linux amd64
  • ros uwb2world坐标转换python示例

    ros uwb2world坐标转换python示例 span class token comment coding 61 utf 8 span span class token comment usr bin env python span
  • ARUCO marker的解释

    markers for ARUCO 一种汉明 海明 码的格子图 如图 百度百科解释汉明码规则概要 使用奇偶校验 具有一位纠错能力 校验位在2的次幂位置1 2 4 8 16 32 具体参看 https baike baidu com item
  • 使用ros_control ros_controllers 的牛刀真实驱动舵机手臂的源码

    现场 rqt graph 在一个陌生的框架下写代码 xff0c 免不了有很多疑问与槽点 不了解框架结构 xff0c 千头万续 xff0c 无从下手 xff0c 说不清 xff0c 理还乱 资料少没有文档 xff0c 要读懂程序猿的心 xff
  • 经典的pid公式,好脑子不如烂笔头。

    这个算法涉及昨天 xff0c 今天 xff0c 明天 思路就是以史为鉴 xff0c 预测明天 xff0c 改革当前
  • c++对8位灰度图进行二值化处理

    对灰度图进行位二值化 xff0c 输入图像像素部分的宽度和高度以及存储灰度像素值 得一维数组 xff0c 对灰度值进行直方图统计 xff0c 通过OSTU大律法公式 xff0c 确定自动灰度 图的阈值 xff0c 进而进行二值化处理 xff
  • vue 数组常用方法(总结)

    vue 数组常用方法 操作原数组push item pop shift unshift item n splice startIndex endIndex sort reverse 返回新数组slice startIndex endInde
  • 【亲测可用】kali linux 2020.1 设置为中文方法

    目录 0x00 提示0x01 更换更新源0x02 默认语言选择0x03 安装中文字体0x04 重启 xff0c 完成0x05 参考文章 kali 2020 1可用 进入我们的正题 xff0c 修改为中文的步骤 0x00 提示 由于kali
  • QT的TCP应用-传输图片

    1 server h span class token macro property span class token directive hash span span class token directive keyword ifnde