Qt TCP Socket Programming _QT

Source: Internet
Author: User
Tags emit

"Learning Notes"

Qtcpsever is used for listening, qtcpsocket for connecting clients and server.

Client Connection server is very simple, connecttohost (qhostaddress ("IP", 666), the completion of IP and port can, after the successful connection, and then associated with the signal readyread () can read the server sent over the data

The server first listens on a port to see if there is a machine attached to the port, and then there are two ways to obtain the socket that the client connects to:

1: Associated signal newconnection (), in the process of accepting the connection, there should be a queue, waiting for the connection will be placed in the connection queue, in the corresponding slot function through the Nextpendingconnection function can get the socket, and then can communicate, Communication or through the readyread () signal, note: This way the returned socket is not available for another thread

2: Another way is to inherit the Qtcpsocket class override Incomingconnection (Qintptr socketdescriptor) function, which is called by the system when there is a connection, socketdescriptor as a socket descriptor, Use this descriptor to create a socket on it, that is, setsocketdescriptor this function, describing Fu to this function parameter.


Here is my reference to the test code written on the Web, you can have multiple clients connected to the same port of the service to communicate with each other



Service side:

ChatSever.h

#include <QObject>
#include <qtcpserver.h>
#include <QList>
#include <tcpsocket.h>
Class Chatsever:public Qtcpserver
{
    Q_object
Public
    Explicit Chatsever (QObject *parent = 0, int port = 0);
    Overload
    void incomingconnection (int handle);
    void Sendmsgtoclient (QString strMsg, int nlength);
Private
    Qlist<tcpsocket*> M_clientsocketlst;    Used to save the client list
Signals:
Public Slots:
    void Updateclientsdata (QString msg, int length);
    void slotdisconnected (int descriptor);
};


ChatSever.cpp

#include "Chatsever.h"
Chatsever::chatsever (QObject *parent, int port): qtcpserver (parent)
{
    Listening
    Listen (qhostaddress::any, port);
}
void chatsever::incomingconnection (int handle)
{
    tcpsocket* clientsocket = new Tcpsocket (this);
    Clientsocket->setsocketdescriptor (handle);
    M_clientsocketlst.append (Clientsocket);
    Connect (Clientsocket, SIGNAL (Updateclientsdata (Qstring,int)), this, SLOT (Updateclientsdata (Qstring,int)));
    A socket disconnect deletes the corresponding object from the underlying list
    Connect (Clientsocket, SIGNAL (disconed (int)), this, SLOT (slotdisconnected (int)));
}
void Chatsever::sendmsgtoclient (QString strMsg, int nlength)
{
    Updateclientsdata (STRMSG, nlength);
}
void Chatsever::updateclientsdata (QString msg, int length)
{
    for (int i = 0; i < M_clientsocketlst.count (); ++i)
    {
        qtcpsocket* itemclient = m_clientsocketlst.at (i);
        if (Itemclient->write () (Msg.tolatin1 (). Data (), length)!= length)
        {
            Qdebug () << "There is data loss";
            Continue
        }
    }
}
Deletes the specified socket object
void chatsever::slotdisconnected (int descriptor)
{
    Qdebug () << "slotdisconnected";
    for (int i = 0; i < M_clientsocketlst.count (); ++i)
    {
        qtcpsocket* item = m_clientsocketlst.at (i);
        if (item->socketdescriptor () = = descriptor)
        {
            M_clientsocketlst.removeat (i);
            Qdebug () << QString ("Socket list =:%1"). Arg (M_clientsocketlst.count ());
            Return
        }
    }
}

TcpSocket.h

#include <QObject>
#include <QTcpSocket>
Class Tcpsocket:public Qtcpsocket
{
    Q_object
Public
    Explicit Tcpsocket (QObject *parent = 0);
Signals:
    void Updateclientsdata (QString, int);
    void disconed (int);
Public Slots:
    void Datarecived ();
    void slotdisconnected ();
};

TcpSocket.cpp

#include "Tcpsocket.h"
Tcpsocket::tcpsocket (QObject *parent): Qtcpsocket (parent)
{
    Establish a slot function to handle the client
    Connect (this, SIGNAL (Readyread ()), this, SLOT (datarecived ()));
    Connect (this, SIGNAL (disconnected ()), this, SLOT (slotdisconnected ()));
}
Read Client Information
void Tcpsocket::d atarecived ()
{
    while (bytesavailable () > 0) {//seemingly solves the problem of the sender Sticky pack, plus the good
        Char buf[1024] = {0};
        int nlength = bytesavailable (); Returns the number of available bytes
        Read (buf, nlength);
        QString str = BUF;
        Emit Updateclientsdata (str, nlength);
    }
}
void tcpsocket::slotdisconnected ()
{
    Qdebug () << "slotdisconnected";
    Emit disconed (Socketdescriptor ());
}

ChatSeverUI.h

#include <QWidget>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QTcpServer>
#include "Chatsever.h"
Namespace Ui {
Class Socketsever;
}
Class Chatseverui:public Qwidget
{
    Q_object
Public
    Explicit Chatseverui (Qwidget *parent = 0);
    ~chatseverui ();
    void Initsocket ();
Public Slots:
    void Acceptconnection ();
    void ReadClient ();
Private Slots:
    void on_pushbutton_clicked ();
Private
    Ui::socketsever *ui;
    qtcpserver* M_sever;
    Qtcpsocket* m_clientconet;
    chatsever*  M_chatsever;
};

ChatSeverUI.cpp

#include "ChatseverUI.h"
#include "Ui_socketsever.h"
#include <QtNetwork/qhostaddress.h>
Chatseverui::chatseverui (Qwidget *parent):
    Qwidget (parent),
    UI (New Ui::socketsever)
{
    UI->SETUPUI (this);
    M_sever = NULL;
    M_clientconet = NULL;
    M_chatsever = NULL;
    Initsocket ();
}
Chatseverui::~chatseverui ()
{
    Delete UI;
}
void Chatseverui::initsocket ()
{
    /*
     *  Method 1
    M_sever = new Qtcpserver (this);
    M_sever->listen (Qhostaddress::any, 6666);
    Connect (M_sever, SIGNAL (Newconnection ()), this, SLOT (Acceptconnection ()));
*/
    Method 2
    M_chatsever = new Chatsever (this, 6666);
    if (!m_chatsever->islistening ())
    {
        Qdebug () << QString ("Unable to start sever:%1"). Arg (m_chatsever->errorstring ());
    }
}
/*
void Chatseverui::acceptconnection ()
{
    M_clientconet = M_sever->nextpendingconnection ();
    Connect (m_clientconet, SIGNAL (Readyread ()), this, SLOT (ReadClient ()));
}
void Chatseverui::readclient ()
{
    QString str = M_clientconet->readall ();
    Ui->severlabel->settext (str);
}
*/
void Chatseverui::on_pushbutton_clicked ()
{
    QString str = Ui->severedit->text ();
    M_clientconet->write (Str.tolatin1 (). data ());
    M_chatsever->sendmsgtoclient (Str.tolatin1 (). Data (), str.length ());
}

The main function is simple, it just shows the windows.

    Chatclientui client1;
    Client1.setwindowtitle ("Client");
    Client1.show ();
    Chatclientui Client2;
    Client2.setwindowtitle ("Client");
    Client2.show ();
    Chatclientui Client3;
    Client3.setwindowtitle ("Client");
    Client3.show ();
    Chatseverui Sever;
    Sever.setwindowtitle ("Sever");
    Sever.show ();

Interface is designed with Qtdesign, here is no longer said, beginners notes, if there is a wrong place to welcome corrections, common progress

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.