Design and implementation of computer network course design and network chat program

Posted by intenz on Fri, 11 Feb 2022 09:24:44 +0100

  • Experimental topic

Design and implementation of network chat program

  • Experimental purpose

1. Understand Socket The principle of communication, learn to use Socket for simple network programming, and write a chat program on this basis.

2. Understand Qt programming and be familiar with C + + language.

  • overall design

1. Background knowledge

Socket is an abstract layer through which applications can send or receive data, and open, read, write and close it like files. Sockets allow applications to insert I/O into the network and communicate with other applications in the network. A network socket is a combination of an IP address and a port.

Transmission Control Protocol (TCP) is a connection oriented, reliable and byte stream based transport layer communication protocol. User Datagram Protocol (UDP) is a transport layer communication protocol that can send encapsulated IP packets without establishing a connection. It does not provide packet Grouping, assembly, packet sorting, message arrival confirmation, flow control and other functions.

Qt is often used as a GUI library to develop graphical interface applications, but this is not the whole of Qt; In addition to drawing beautiful interfaces (including controls, layout and interaction), Qt also includes many other functions, such as multithreading, accessing database, image processing, audio and video processing, network communication, file operation, etc. These QTS have been built in.

2. Basic principles

Socket is an implementation of the "open read / write close" mode. The server and client maintain a "file" respectively. After the connection is established and opened, the content can be written to the file for the other party to read or read the other party's content. The file is closed at the end of communication.

Socket is an abstract layer between the application layer and the transport layer. It abstracts the complex operation of TCP/IP layer into several simple interfaces, and the supply layer calls to realize the communication of processes in the network.

Socket ensures the communication between different computers. For the website, the communication model is the communication between the server and the client. A socket object is established at both ends, and then the data is transmitted through the socket object. Usually, the server is in an infinite loop, waiting for the client to connect.

3. Module introduction

(1) Server side: monitor all IPS on the network. If there is a connection request, connect and communicate one-to-one with the client.

(2) Client: connect to the server through the given port number and Ip address to communicate with the server.

4. Design steps

(1) Server

  • Load socket library and create socket (QTcpSocket)
  • Bind to a socket and an IP address (bind)
  • Set the socket to listen mode and wait for the connection request (listen())
  • After the request arrives, accept the connection request and return a new socket corresponding to the connection (accept())
  • Communicate with the client using the returned socket (send())
  • Return and wait for another connection request
  • Close the socket and close the loaded socket library

(2) Client

  • Load socket library and create socket (QTcpSocket)
  • Send a connection request to the server (connect())
  • Communicate with the server (send())
  • Close the socket and close the loaded socket library

 

  • detailed design

1. Program flow chart

2. Code

(1) server side

Code composition:

server.h

#ifndef SERVER_H
#define SERVER_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QTcpServer>

QT_BEGIN_NAMESPACE
namespace Ui { class server; }
QT_END_NAMESPACE

class server : public QMainWindow
{
    Q_OBJECT

public:
    server(QWidget *parent = nullptr);
    ~server();

private:
    Ui::server *ui;
    QTcpServer *Server;
    QTcpSocket *Socket;
private slots:
    void Listen();
    void send();
    void newConnect();
    void Read_data();
    void DisConnect();

};
#endif // SERVER_H

 main.cpp

#include "server.h"

#include <QApplication>

int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    server w;
    w.show();
    return a.exec();
}

 server.cpp

#include "server.h"
#include "ui_server.h"
#include <QMessageBox>


server::server(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::server)
{
    ui->setupUi(this);
    ui->Port->setText("2770");
    connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(Listen()));
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(send()));

}

server::~server()
{
    delete ui;
}

void server::Listen(){
        Server = new QTcpServer();
        //int port = ui->Port->text().toInt();
        if(!Server->listen(QHostAddress::Any, 2770))
        {
            QMessageBox::information(this, "QT Network Communications", "Server side listening failed!");
            return;
        }
        else
        {
            QMessageBox::information(this, "QT Network Communications", "Server listening succeeded!");
        }
        connect(Server, SIGNAL(newConnection()), this, SLOT(newConnect()));
}
void server::send(){
        qint64 writes=Socket->write(ui->textEdit->toPlainText().toLatin1());
        bool Bool=Socket->flush();
        if(writes==-1&&Bool!=1)
        {
            QMessageBox::warning(this, "QT Network Communications", "Failed to send data, please send again!");
            return;
        }
        ui->listWidget->addItem(QString(ui->textEdit->toPlainText()).toLocal8Bit());
        ui->textEdit->clear();
}
void server::Read_data(){
    QByteArray array;
    array.resize(Socket->bytesAvailable());//Set the space size according to the readable data
    array=Socket->readLine();
    ui->listWidget->addItem("[Client]:"+array);
}
void server::newConnect(){
    Socket=Server->nextPendingConnection();
    if(!Socket){
        QMessageBox::warning(this, "warning", "The client connection is not obtained correctly!");
               return;
           }
           else
           {
               QMessageBox::information(this, "QT Network Communications", "Successfully accepted the client's connection");
           connect(Socket, SIGNAL(readyRead()), this, SLOT(Read_data()));
               connect(Socket, SIGNAL(disconnected()), this, SLOT(DisConnect()));

    }
}
void server::DisConnect(){
    QMessageBox::information(this, "QT Network Communications", "Disconnected from client");
        return;
}

 server.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>server</class>
 <widget class="QMainWindow" name="server">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>465</width>
    <height>556</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>server</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QTextEdit" name="textEdit">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>410</y>
      <width>301</width>
      <height>51</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>340</x>
      <y>440</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>send out</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_3">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>40</y>
      <width>81</width>
      <height>20</height>
     </rect>
    </property>
    <property name="text">
     <string>Server port number</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="Port">
    <property name="geometry">
     <rect>
      <x>110</x>
      <y>40</y>
      <width>113</width>
      <height>20</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton_2">
    <property name="geometry">
     <rect>
      <x>240</x>
      <y>40</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>initialization</string>
    </property>
   </widget>
   <widget class="QListWidget" name="listWidget">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>80</y>
      <width>301</width>
      <height>311</height>
     </rect>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>465</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

(2) client

Code composition:

client.h

#ifndef CLIENT_H
#define CLIENT_H

#include <QMainWindow>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class client; }
QT_END_NAMESPACE

class client : public QMainWindow
{
    Q_OBJECT

public:
    client(QWidget *parent = nullptr);
    ~client();

private:
    Ui::client *ui;
private slots:
    void connection();
    void send();
    void read_data();
private:
    QTcpSocket *Socket;
};
#endif // CLIENT_H

 main.cpp

#include "client.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    client w;
    w.show();
    return a.exec();
}

client.cpp

#include "client.h"
#include "ui_client.h"
#include <QMessageBox>
#include <QtNetwork>
#include <QThread>


client::client(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::client)
{

    ui->setupUi(this);
    ui->Ip->setText("127.0.0.1");
    ui->Port->setText("2770");
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(connection()));
    connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(send()));
}

client::~client()
{
    delete ui;
}
void client::connection(){
    Socket = new QTcpSocket(this);
        QString ip = ui->Ip->text();
      //  int port = ui->Port->text().toInt();
        Socket->connectToHost(QHostAddress("127.0.0.1"), 2770);
        if(!Socket->waitForConnected(30000))
        {
            QMessageBox::warning(this, "warning", "Failed to connect to the server!");
            return;
        }
        QMessageBox::information(this,"Qt","success!");
         connect(Socket, SIGNAL(readyRead()), this, SLOT(read_data()));
}
void client::send(){
    //Gets the content in the TextEdit control
       QString data=ui->send->toPlainText().toUtf8();
       QByteArray ba=data.toLocal8Bit();
       int sendRe = Socket->write(ba);
       bool bools=Socket->flush();
       if(sendRe == -1&&bools!=1)
       {
            QMessageBox::information(this, "QT Network Communications", "Failed to send data to the server!");
            return;
       }
       ui->listWidget->addItem(QString(ui->send->toPlainText()).toLocal8Bit());
       ui->send->clear();


}
void client::read_data(){
            QByteArray array;
            array.resize(Socket->bytesAvailable());//Set the space size according to the readable data
            array=Socket->readLine();
            ui->listWidget->addItem("[Server]:"+array);


}

client.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>client</class>
 <widget class="QMainWindow" name="client">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>373</width>
    <height>573</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>client</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>30</y>
      <width>61</width>
      <height>21</height>
     </rect>
    </property>
    <property name="text">
     <string>Server IP</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>70</y>
      <width>81</width>
      <height>21</height>
     </rect>
    </property>
    <property name="text">
     <string>Server port number</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="Ip">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>30</y>
      <width>113</width>
      <height>20</height>
     </rect>
    </property>
   </widget>
   <widget class="QLineEdit" name="Port">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>70</y>
      <width>113</width>
      <height>20</height>
     </rect>
    </property>
   </widget>
   <widget class="QTextEdit" name="send">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>360</y>
      <width>271</width>
      <height>51</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>240</x>
      <y>50</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>connect</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton_2">
    <property name="geometry">
     <rect>
      <x>250</x>
      <y>430</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>send out</string>
    </property>
   </widget>
   <widget class="QListWidget" name="listWidget">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>100</y>
      <width>271</width>
      <height>241</height>
     </rect>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>373</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>
  • Experimental results and analysis

1. Experimental results

 

 

2. Analysis

First, you must open the server to let the server establish monitoring, and then open the client to establish a connection with the server. The client can send a message to the server first, and then continue to send after receiving the reply from the server. One disadvantage is that you must chat back and forth. The client cannot send multiple messages to the server, and the server cannot.

  • Summary and experience

This experiment is the first experiment. At the beginning, I got this question without any ideas at all. After reading Appendix I, I gradually got a little understanding of network communication. Before that, we haven't come into contact with a series of programming ideas of using socket interface to realize network protocol. Our understanding of TCP and UDP is only limited to theoretical knowledge and will not be applied to experiments at all. In Experiment 1, I learned to use socket to realize communication, and also understood a series of programming protocols. At the same time, I had a deeper understanding of the use process of winsock as a whole. By reading the source code, I had a deep understanding of the essence and process of TCP/IP protocol in program operation.

Topics: C++ Qt computer networks