• 【window环境、Linux环境、QT三种方法实现TCP通信】


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    前言

    大多数项目都在Linux系列的操作系统下开发服务器端,而多数客户端是在Windows平台下开发的。不仅如此,有时应用程序还需要在两个平台之间相互切换。因此,学习套接字编程的过程中,有必要兼顾Windows和Linux两大平台。另外,这两大平台下的套接字编程非常类似,如果把其中相似的部分放在一起讲解,将大大提高学习效率。只要理解好其中一个平台下的网络编程方法,就很容易通过分析差异掌握另一平台。因为不论什么方式实现,底层的逻辑都是完全一致的。


    一、Windows环境下实现TCP通信

    为了在Winsock基础上开发网络程序,需要做如下准备,以下两个文件都是系统自带的,包含时注意目标平台版本与库的版本一致。
    导入头文件winsock2.h。
    链接ws2_32.lib库(库名称和链接目录)。

    1.服务器

    #include 
    #include 
    #include 
    
    void ErrorHandling(char *message)
     {
    	fputs(message, stderr);
    	fputs("\n", stderr);
    	exit(1);
    }
    
    int main(int argc, char * argv[])
     {
    	WSADATA wsaData;
    	SOCKET hServSock, hClntSock;
    	SOCKADDR_IN servAddr, clntAddr;
    	int szClntAddr;
    	char message[] = "Hello World!";
    	if (argc != 2) 
    	{
    		printf("Usage : %s ", argv[0]);
    		exit(1);
    	}
    
    	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    		ErrorHandling("WSAStartup() error!");
    
    	hServSock = socket(PF_INET, SOCK_STREAM, 0);
    	if (hServSock == INVALID_SOCKET)
    		ErrorHandling("socket() error!");
    
    	memset(&servAddr, 0, sizeof(servAddr));
    	servAddr.sin_family = AF_INET;
    	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    	servAddr.sin_port = htons(atoi(argv[1]));
    
    	if (bind(hServSock, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
    		ErrorHandling("bind() error!");
    
    	if (listen(hServSock, 5) == SOCKET_ERROR)
    		ErrorHandling("listen() error!");
    
    	szClntAddr = sizeof(clntAddr);
    	hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &szClntAddr);
    	if (hClntSock == INVALID_SOCKET)
    		ErrorHandling("accept() error!");
    	fputs("sending message...", stderr);
    	fputs("", stderr);
    	send(hClntSock, message, sizeof(message), 0);
    	closesocket(hClntSock);
    	closesocket(hServSock);
    	WSACleanup();
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    2.客户端

    #include 
    #include 
    #include 
    void ErrorHandling(char* message);
    
    int main(int argc, char *argv[]) 
    {
    	WSADATA wsaData;
    	SOCKET hSocket;
    	SOCKADDR_IN servAddr;
    
    	char message[30];
    	int strlen;
    	if (argc != 3) 
    	{
    		printf("Usage: %s  ", argv[0]);
    	exit(1);
    	}
    
    	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    		ErrorHandling("WSAStartup() error!");
    
    	hSocket = socket(PF_INET, SOCK_STREAM, 0);
    	if (hSocket == INVALID_SOCKET)
    		ErrorHandling("socket() error!");
    
    	memset(&servAddr, 0, sizeof(servAddr));
    	servAddr.sin_family = AF_INET;
    	servAddr.sin_addr.s_addr = inet_addr(argv[1]);
    	servAddr.sin_port = htons(atoi(argv[2]));
    
    	if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
    		ErrorHandling("connect() error!");
    
    	strlen = recv(hSocket, message, sizeof(message) - 1, 0);
    	if (strlen == -1)
    		ErrorHandling("read() error!");
    
    	printf("Message from server:%s", message);
    	closesocket(hSocket);
    	WSACleanup();
    	return 0;
    }
    
    void ErrorHandling(char * message) {
    	fputs(message, stderr);
    	fputc('\n', stderr);
    	exit(1);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    3.运行

    运行时直接进入到可执行程序文件,使用命令行运行

    C:\tcpip>tcp_win_server 9190
    
    • 1
    C:\tcpip>tcp_win_client 127.0.0.1 9190
    
    • 1

    二、Linux环境下实现TCP通信

    1.服务端

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    void error_handling(char *message);
    int main(int argc,char *argv[])
    {
    	int serv sock;
    	int clnt sock;
    	struct sockaddr in serv addr;
    	struct sockaddr in clnt addr;
    	socklen t clnt addr size;
    	char message[]="Hello World!";
    	if(argc!=2)
    	{
    		printf("Usage :%s\n",argv[0]);
    		exit(1);
    	}
    	serv sock=Socket(PF INET,SOCK STREAM,0);
    	if(serv sock ==-1)
    		error_handling("socket() error");
    	memset(&serv_addr,0,sizeof(serv addr));
    	serv_addr.sin_family=AF INET;
    	serv_addr.sin_addr.s addr=htonl(INADDR ANY);
    	serv_addr.sin_port=htons(atoi(argv[1]));
    	if(bind(serv_sock,(struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1)
    		error_handling("bind() error");
    	if(listen(serv sock,5)==-1)
    		error_handling("listen() error");
    	clnt addr size=sizeof(clnt addr);
    	cInt sock=accept(sery sock,(struct sockaddr*)&cInt addr,&cInt addr size);
    	if(clnt sock==-1)
    		error_handling("accept() error");
    	write(clnt_sock,message,sizeof(message));
    	close(clnt sock);
    	close(serv sock);return 0;
    }
    void error handling(char *message)
    {
    	fputs(message, stderr);
    	fputc('\n',stderr);
    	exit(1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    2.客户端

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    void error handling(char *message);
    int main(int argc, char* argv[])
    {
    	int sock;
    	struct sockaddr_in serv_addr;
    	char message[30];
    	int str_len;
    	if(argc!-3)
    	{
    		printf("Usage :%s\n",argv[0]);
    		exit(1);
    	}
    	sock=socket(PF INET,SOCK STREAM, 0);
    	if(sock == -1)
    		error_handling("socket() error")
    	memset(&serv addr,0,sizeof(serv addr));
    	serv addr.sin family=AF INET;
    	serv addr.sin addr.s addr-inet addr(argv[1]);
    	serv_addr.sin port=htons(atoi(argv[2]));
    	if(connect(sock,(struct sockaddr*)&serv addr,sizeof(serv_addr))==-1)
    		error_handling("connect() error!");
    	str len=read(sock,message,sizeof(message)-1);
    	if(str len=--1)
    		error_handling("read()error!");
    	printf("Message from server :Xs n",message);
    	close(sock);
    	return 0;
    }
    void error handling(char*message)
    {
    	fputs(message, stderr)fputc('\n',stderr);
    	exit(1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    三、Qt实现TCP通信

    相对于前边两种方法,QT进行了一定封装,使用起来更加简洁。
    在这里插入图片描述

    1.服务端

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include  
    #if _MSC_VER >= 1600
    #pragma execution_character_set("utf-8")
    #endif
    
    QString MainWindow::getLocalIP()
    {
        //获取本机IPv4地址
        //! 本地主机名, QHostInfo 的静态函数 localHostName()可获取本机的主机名
        QString hostName = QHostInfo::localHostName();
        //! 返回指定的主机名的IP地址
        QHostInfo hostInfo = QHostInfo::fromName(hostName);
        QString localIP = "";
        //! 返回与 hostName()主机关联的IP地址列表
        QList<QHostAddress> addList = hostInfo.addresses();//
    
        for (int i = 0; i < addList.count(); i++)
        {
            QHostAddress aHost = addList.at(i);
            if (QAbstractSocket::IPv4Protocol == aHost.protocol())
            {
                //192.168.23.114
                localIP=aHost.toString();
                break;
            }
        }
        return localIP;
    }
    
    void MainWindow::closeEvent(QCloseEvent *event)
    {//关闭窗口时停止监听
        if (tcpServer->isListening())
            tcpServer->close();;//停止网络监听
        event->accept();
    }
    
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        LabListen=new QLabel("监听状态:");
        LabListen->setMinimumWidth(150);
        ui->statusBar->addWidget(LabListen);
    
        LabSocketState=new QLabel("Socket状态:");//
        LabSocketState->setMinimumWidth(200);
        ui->statusBar->addWidget(LabSocketState);
        //本机IP
        QString localIP = getLocalIP();
        this->setWindowTitle(this->windowTitle()+"----本机IP:"+localIP);
        ui->comboIP->addItem(localIP);
        //! tcp服务端
        tcpServer = new QTcpServer(this);
        //! 如果有新的连接
        connect(tcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    //! 服务端有新的连接时
    void MainWindow::onNewConnection()
    {
    //    ui->plainTextEdit->appendPlainText("有新连接");
        //! 创建socket,返回下一个等待接入的连接
        tcpSocket = tcpServer->nextPendingConnection();
        //! connectToHost()成功连接到服务器后发射此信号,连接成功后显示
        connect(tcpSocket, SIGNAL(connected()), this, SLOT(onClientConnected()));
        //! 客户端接入时
        onClientConnected();
        //! 当socket断开连接后发射此信号
        connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
        //! 当socket的状态变化时发射此信号,参数socketState表示了socket当前的状态
        connect(tcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,
                SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
        onSocketStateChange(tcpSocket->state());
        //! 当缓冲区有新数据需要读取时发射此信号,在此信号的槽函数里读取缓冲区的数据
        connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));
    }
    
    //socket状态变化时
    void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
    {
        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 MainWindow::onClientConnected()
    {
        ui->plainTextEdit->appendPlainText("**client socket connected");
        ui->plainTextEdit->appendPlainText("**peer name:" + tcpSocket->peerName());
        //! 在已连接状态下,返回对方socket的地址
        ui->plainTextEdit->appendPlainText("**peer address:" + tcpSocket->peerAddress().toString());
        ui->plainTextEdit->appendPlainText("**peer port:" + QString::number(tcpSocket->peerPort()));
    }
    
    void MainWindow::onClientDisconnected()
    {//客户端断开连接时
        ui->plainTextEdit->appendPlainText("**client socket disconnected");
        tcpSocket->deleteLater();
        //    deleteLater();//QObject::deleteLater();
    }
    
    void MainWindow::onSocketReadyRead()
    {//读取缓冲区行文本
    //    QStringList   lines;
        while(tcpSocket->canReadLine())
            ui->plainTextEdit->appendPlainText("[in] " + tcpSocket->readLine());
    //        lines.append(clientConnection->readLine());
    }
    
    //开始监听
    void MainWindow::on_actStart_triggered()
    {
        //! IP地址
        QString IP = ui->comboIP->currentText();
        //! 端口
        quint16 port = ui->spinPort->value();
        QHostAddress addr(IP);
        tcpServer->listen(addr, port);//
    //    tcpServer->listen(QHostAddress::LocalHost,port);// Equivalent to QHostAddress("127.0.0.1").
        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 MainWindow::on_actStop_triggered()
    {//停止监听
        if (tcpServer->isListening()) //tcpServer正在监听
        {
            tcpServer->close();//停止监听
            ui->actStart->setEnabled(true);
            ui->actStop->setEnabled(false);
            LabListen->setText("监听状态:已停止监听");
        }
    }
    
    void MainWindow::on_actClear_triggered()
    {
        ui->plainTextEdit->clear();
    }
    
    void MainWindow::on_btnSend_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 MainWindow::on_actHostInfo_triggered()
    {//获取本机地址
        QString hostName=QHostInfo::localHostName();//本地主机名
        ui->plainTextEdit->appendPlainText("本机主机名:"+hostName+"\n");
        QHostInfo   hostInfo=QHostInfo::fromName(hostName);
    
        QList<QHostAddress> addList=hostInfo.addresses();//
        if (!addList.isEmpty())
        for (int i=0;i<addList.count();i++)
        {
            QHostAddress aHost=addList.at(i);
            if (QAbstractSocket::IPv4Protocol==aHost.protocol())
            {
                QString IP=aHost.toString();
                ui->plainTextEdit->appendPlainText("本机IP地址:"+aHost.toString());
                if (ui->comboIP->findText(IP)<0)
                    ui->comboIP->addItem(IP);
            }
        }
    
    }
    
    mainwindow.h
    
    ```cpp
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    #include 
    #include    
    #include    
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    private:
        QLabel  *LabListen;//状态栏标签
        QLabel  *LabSocketState;//状态栏标签
        QTcpServer *tcpServer; //TCP服务器
        QTcpSocket *tcpSocket;//TCP通讯的Socket
        QString getLocalIP();//获取本机IP地址
    protected:
        void   closeEvent(QCloseEvent *event);
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    private slots:
    //自定义槽函数
        void    onNewConnection();//QTcpServer的newConnection()信号
        void    onSocketStateChange(QAbstractSocket::SocketState socketState);
        void    onClientConnected(); //Client Socket connected
        void    onClientDisconnected();//Client Socket disconnected
        void    onSocketReadyRead();//读取socket传入的数据
    //UI生成的
        void on_actStart_triggered();
        void on_actStop_triggered();
        void on_actClear_triggered();
        void on_btnSend_clicked();
        void on_actHostInfo_triggered();
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250

    1.客户端

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include  
    #include  
    #if _MSC_VER >= 1600
    #pragma execution_character_set("utf-8")
    #endif
    QString MainWindow::getLocalIP()
    {
        QString hostName = QHostInfo::localHostName();//本地主机名
        QHostInfo hostInfo = QHostInfo::fromName(hostName);
        QString localIP = "";
        QList<QHostAddress> addList = hostInfo.addresses();//
        for (int i = 0; i < addList.count(); i++)
        {
            QHostAddress aHost = addList.at(i);
            if (QAbstractSocket::IPv4Protocol == aHost.protocol())
            {
                localIP=aHost.toString();
                break;
            }
        }
        return localIP;
    }
    void MainWindow::closeEvent(QCloseEvent *event)
    {
        if (tcpClient->state()==QAbstractSocket::ConnectedState)
            tcpClient->disconnectFromHost();
        event->accept();
    }
    
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        tcpClient = new QTcpSocket(this); //创建socket变量
        LabSocketState=new QLabel("Socket状态:");//状态栏标签
        LabSocketState->setMinimumWidth(250);
        ui->statusBar->addWidget(LabSocketState);
        //本机IP
        QString localIP = getLocalIP();
        this->setWindowTitle(this->windowTitle() + "----本机IP:" + localIP);
        ui->comboServer->addItem(localIP);
    
        connect(tcpClient,SIGNAL(connected()),this,SLOT(onConnected()));
        connect(tcpClient,SIGNAL(disconnected()),this,SLOT(onDisconnected()));
        connect(tcpClient,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,
                SLOT(onSocketStateChange(QAbstractSocket::SocketState)));
        connect(tcpClient,SIGNAL(readyRead()),this,SLOT(onSocketReadyRead()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::onConnected()
    { //connected()信号槽函数
        ui->plainTextEdit->appendPlainText("**已连接到服务器");
        ui->plainTextEdit->appendPlainText("**peer address:" + tcpClient->peerAddress().toString());
        ui->plainTextEdit->appendPlainText("**peer port:" + QString::number(tcpClient->peerPort()));
        ui->actConnect->setEnabled(false);
        ui->actDisconnect->setEnabled(true);
    }
    
    void MainWindow::onDisconnected()
    {//disConnected()信号槽函数
        ui->plainTextEdit->appendPlainText("**已断开与服务器的连接");
        ui->actConnect->setEnabled(true);
        ui->actDisconnect->setEnabled(false);
    }
    
    void MainWindow::onSocketReadyRead()
    {//readyRead()信号槽函数
        while(tcpClient->canReadLine())
            ui->plainTextEdit->appendPlainText("[in] "+tcpClient->readLine());
    }
    
    void MainWindow::onSocketStateChange(QAbstractSocket::SocketState socketState)
    {//stateChange()信号槽函数
        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 MainWindow::on_actConnect_triggered()
    {//连接到服务器
        QString     addr=ui->comboServer->currentText();
        quint16     port=ui->spinPort->value();
        tcpClient->connectToHost(addr,port);
    //    tcpClient->connectToHost(QHostAddress::LocalHost,port);
    }
    
    void MainWindow::on_actDisconnect_triggered()
    {//断开与服务器的连接
        if (tcpClient->state()==QAbstractSocket::ConnectedState)
            tcpClient->disconnectFromHost();
    }
    
    void MainWindow::on_actClear_triggered()
    {
        ui->plainTextEdit->clear();
    }
    
    void MainWindow::on_btnSend_clicked()
    {//发送数据
        QString  msg=ui->editMsg->text();
        ui->plainTextEdit->appendPlainText("[out] "+msg);
        ui->editMsg->clear();
        ui->editMsg->setFocus();
        QByteArray str = msg.toUtf8();
        str.append('\n');
        tcpClient->write(str);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    #include    
    #include    
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    private:
        QTcpSocket  *tcpClient;  //socket
        QLabel  *LabSocketState;  //状态栏显示标签
    
        QString getLocalIP();//获取本机IP地址
    protected:
        void    closeEvent(QCloseEvent *event);
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
    //自定义槽函数
        void    onConnected();
        void    onDisconnected();
        void    onSocketStateChange(QAbstractSocket::SocketState socketState);
        void    onSocketReadyRead();//读取socket传入的数据
    //
        void on_actConnect_triggered();
    
        void on_actDisconnect_triggered();
    
        void on_actClear_triggered();
    
        void on_btnSend_clicked();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    总结

    以上就是今天要讲的内容,本文整理了三种实现TCP通信的方法,从上层到偏底层,对于新手理解通信原理有极大帮助。

  • 相关阅读:
    python 文件操作
    5. `sklearn`下的线性回归
    AWR仿真报错invalid noise data found
    GoFrame+Vue+ElementUI极速开发框架
    Redis Centos 7 安装过程
    java抽象类
    模型可解释性
    VLAN通讯
    什么是软件测试?零基础入门知识要点总结篇,5分钟带你快速了解
    Eavesdropping(窃听机制)在机器学习中的用法
  • 原文地址:https://blog.csdn.net/weixin_42723793/article/details/137965538