blackfire531
3/31/2020 - 10:40 AM

qt使用TCP Server协议


#include <QtNetwork>

QTcpServer *socket_server;
QTcpSocket *m_socket_server;
bool tcp_server_link_flag;
quint16 portNumber_server;
void tcp_processData_server(QByteArray buf);

public slots:
    void tcp_readData_server();
    void tcp_connected_server();
    void tcp_disconnected_server();
    void tcp_error_server(QAbstractSocket::SocketError);

//作为服务器端
socket_server = new QTcpServer;
tcp_server_link_flag = false;
connect(socket_server, &QTcpServer::newConnection,this, &MainWindow::tcp_connected_server);//客户端连接消息
connect(socket_server, &QTcpServer::acceptError,this, &MainWindow::tcp_error_server);//错误消息
if(!socket_server->listen(QHostAddress::Any,portNumber_server))//开启连接
{
  qDebug()<<socket_server->errorString();
}
  
/**************************************************************************************/
/*                                    网络相关-server                                 */
/**************************************************************************************/

/**
 * @brief TCP成功连接
 */
void MainWindow::tcp_connected_server()
{
  auto sockt_tmp = socket_server->nextPendingConnection();
  m_socket_server = sockt_tmp;
  m_socket_server->setSocketOption(QAbstractSocket::LowDelayOption,1);

  connect(m_socket_server,&QTcpSocket::readyRead,this,&MainWindow::tcp_readData_server);
  connect(m_socket_server,&QTcpSocket::disconnected,this,&MainWindow::tcp_disconnected_server);

  tcp_server_link_flag = true;
  status_tcp_link_server->setStyleSheet("background-color:rgb(0, 255, 0);color: rgb(0, 0, 0);");
  status_tcp_link_server->setText("客户端已连接");
  qDebug()<<"new connection comming!";
}

/**
 * @brief TCP错误处理
 */
void MainWindow::tcp_error_server(QAbstractSocket::SocketError)
{
  serverAutoUpdate_timer->stop();
  tcp_server_link_flag = false;
  status_tcp_link_server->setStyleSheet("background-color:rgb(255, 255, 0);color: rgb(0, 0, 0);");
  status_tcp_link_server->setText("等待客户端连接");
  qDebug()<<m_socket_server->errorString();
}

/**
 * @brief 服务器收到数据
 */
void MainWindow::tcp_readData_server()
{
  QByteArray recvBuf;
  recvBuf = m_socket_server->readAll();
  tcp_processData_server(recvBuf);//处理数据
  qDebug()<<"recv:"<<recvBuf.toHex()<<recvBuf.length();
}

/**
 * @brief 服务器断开连接
 */
void MainWindow::tcp_disconnected_server()
{
  serverAutoUpdate_timer->stop();
  m_socket_server->close();
  tcp_server_link_flag = false;
  status_tcp_link_server->setStyleSheet("background-color:rgb(255, 255, 0);color: rgb(0, 0, 0);");
  status_tcp_link_server->setText("等待客户端连接");
  qDebug()<<"connection disconnect!";
}

/**
 * @brief 处理tcp server收到的数据
 * @param 待处理数据
 * @通信协议  数据格式: 同步头NTIO |命令|数据        |校验位
 *                        4E 54 49 4F  XX  A1 A2 B1 B2  hh
 *        命令: 0x01 读取DI16和DO16数据,数据填充全0
 *               0x02 返回DI16和DO16数据,DI=0xA1A2(DI16~DI1,每个bit代表一个IO) DO=0xB1B2(DO16~DO1,每个bit代表一个IO)
 *               0x03 设置单独DO,A1A2=0x0000, B1=0x00~0x0f(DO1~DO16), B2:1开0关
 *               0x04 设置全部DO,A1A2=0x0000, B1=0x00, B2:1开0关
 *               0x05 设置定时自动发送DIDO数据,A1A2=0x0000,B1B2=定时时间,单位为毫秒
 *        校验:异或校验,从同步头的0x4E开始到数据B2结束
 */
void MainWindow::tcp_processData_server(QByteArray buf)
{
  quint16 update_time;
  quint8 checksum;
}