Qt: Implementation of qsocket persistent connection (single-thread server)

Source: Internet
Author: User

Put it bluntly: directly add the code

Code function: the client sends a string to the service first. After receiving the string, the server sends the same string (echo string) to the client)

The server side of this demo has been greatly updated on February 14,. The previous program has serious problems (Memory leakage, do not release the port ...),
I am also a newbie. Please forgive me. If you find any problems with this demo, please leave a message and suggestions. Learn together.


Source code:

// Server. h # ifndef chatserver_h # define chatserver_h # include <qtgui> # include <qtnetwork> # include <qtcore> class connectsocket: Public qtcpsocket {q_object public: connectsocket (qobject * parent = 0 ); ~ Connectsocket (); void setdescriptor (INT des) {m_descriptor = des;} signals: void disconnectedsignal (INT); Private slots: void readmessage (); void sendmessage (); void disconnectslot (); Private: // After the network is disconnected, the descriptor is immediately changed to-1. Therefore, save int m_descriptor; qstring m_string; quint16 m_blocksize;}; Class Server: public qtcpserver {q_object public: Server (qobject * parent = 0, int Port = 0); protected: void incomingconnec Tion (INT socketdescriptor); Private: qmap <int, connectsocket *> m_clientdesmap; Public slots: void clientdisconnected (INT);}; Class dialog: Public qdialog {q_object public: dialog (qwidget * parent = 0); Private: qlabel * statuslabel; qpushbutton * quitbutton; server * server ;};# endif // chatserver_h // server. CPP # include "server. H "server: Server (qobject * parent, int port): qtcpserver (parent) {If (! Listen (qhostaddress: Any, Port) {qmessagebox: About (null, "error", "can't connected"); exit (2) ;}} void Server:: incomingconnection (INT descriptor) {connectsocket * socket = new connectsocket (this); Connect (socket, signal (disconnectedsignal (INT), this, slot (clientdisconnected (INT ))); socket-> setsocketdescriptor (descriptor); // commectsocket * must be saved; otherwise, the connection will be automatically disconnected m_clientdesmap [descriptor] = socket; qdebu G () <descriptor <"added"; socket-> setdescriptor (descriptor);} void server: clientdisconnected (INT descriptor) {// when the connection ends, you must delete the corresponding socket; otherwise, memory leakage may occur. M_clientdesmap [descriptor]-> deletelater (); m_clientdesmap.remove (descriptor); qdebug () <descriptor <"removed";} dialog: Dialog (qwidget * parent ): qdialog (parent) {statuslabel = new qlabel; quitbutton = new qpushbutton (TR ("quit"); quitbutton-> setautodefault (false); server = new server (this, 8888); If (! Server-> islistening () {qmessagebox: Critical (this, TR ("Chat Server"), TR ("unable to start the server: % 1. "). arg (server-> errorstring (); close (); return;} qstring IPaddress; qlist <qhostaddress> ipaddresseslist = qnetworkinterface: alladdresses (); for (INT I = 0; I <ipaddresseslist. size (); ++ I) {If (ipaddresseslist. at (I )! = Qhostaddress: localhost & ipaddresseslist. at (I ). toipv4address () {IPaddress = ipaddresseslist. at (I ). tostring (); break;} If (IPaddress. isempty () IPaddress = qhostaddress (qhostaddress: localhost ). tostring (); statuslabel-> settext (TR ("the server is running on \ n \ NIP: % 1 \ nport: % 2 \ n "" Run the fortune client example now. "). arg (IPaddress ). arg (server-> SERVERPORT (); Connect (quitbutton, signal (CLI Cked (), this, slot (close (); qhboxlayout * buttonlayout = new qhboxlayout; buttonlayout-> addstretch (1); buttonlayout-> addwidget (quitbutton ); buttonlayout-> addstretch (1); qvboxlayout * mainlayout = new qvboxlayout; mainlayout-> addwidget (statuslabel); mainlayout-> addlayout (buttonlayout); setlayout (mainlayout ); setwindowtitle (TR ("Chat Server");} connectsocket: connectsocket (qobject * parent) {m_block Size = 0; Connect (this, signal (readyread (), this, slot (readmessage (); Connect (this, signal (disconnected (), this, slot (disconnectslot (); qdebug () <This <"created";} connectsocket ::~ Connectsocket () {qdebug () <This <"deleted";} void connectsocket: readmessage () {qdatastream in (this); In. setversion (qdatastream: qt_4_0); If (m_blocksize = 0) {If (bytesavailable () <(INT) sizeof (quint16) return; In> m_blocksize ;} if (bytesavailable () <m_blocksize) return; In> m_string; m_blocksize = 0; sendmessage () ;}void connectsocket: sendmessage () {qbytearray block; qdatastrea M out (& Block, qiodevice: writeonly); out. setversion (qdatastream: qt_4_0); out <(quint16) 0; out <m_string; out. device ()-> seek (0); out <(quint16) (Block. size ()-sizeof (quint16); write (Block);} void connectsocket: disconnectslot () {emit disconnectedsignal (m_descriptor);} // main. CPP # include "server. H "# include <qtgui/qapplication> int main (INT argc, char * argv []) {qapplication A (argc, argv); D Ialog W; W. show (); Return a.exe C ();} // client. h # ifndef trycli_h _ # define trycli_h _ # include <qtnetwork> # include <qtgui> # include <qtcore> class client: Public qwidget {q_object PRIVATE: bool isconnected; qlineedit * serveripedit; qlabel * label; qlineedit * stredit; qpushbutton * startbutton; qtcpsocket * tcpclient; quint16 blocksize; qstring sendstring; qstring readstring; public: client (); ~ Client (); Public slots: void displayerror (qw.actsocket: socketerror); void newconnect (); void readmessage (); void sendmessage () ;}#endif // client. CPP # include "client. H "# include <qtgui/qmessagebox> # include <qtgui/qhboxlayout> # include <qtevents> client: client () {setwindowtitle (" client "); resize (300,100 ); serveripedit = new qlineedit ("127.0.0.1"); startbutton = new qpushbutton ("Start"); stredit = new qlineedit; label = new qlabel ("emtpy"); isconnected = false; qvboxlayout * layout = new qvboxlayout; Layout-> addwidget (serveripedit ); layout-> addwidget (Label); Layout-> addwidget (stredit); Layout-> addwidget (startbutton); setlayout (layout); tcpclient = new qtcpsocket (this ); connect (startbutton, signal (clicked (), this, slot (newconnect (); Connect (tcpclient, signal (connected () ), This, slot (sendmessage (); Connect (tcpclient, signal (readyread (), this, slot (readmessage (); Connect (tcpclient, signal (error (q1_actsocket: socketerror), this, slot (displayerror (q1_actsocket: socketerror);} client ::~ Client () {} void client: newconnect () {blocksize = 0; If (! Isconnected) {tcpclient-> abort (); tcpclient-> connecttohost (serveripedit-> text (), 8888); isconnected = true;} else sendmessage ();} void client :: sendmessage () {qbytearray block; qdatastream out (& Block, qiodevice: writeonly); out. setversion (qdatastream: qt_4_0); sendstring = stredit-> text (); out <(quint16) 0; out <sendstring; out. device ()-> seek (0); out <(quint16) (Block. size ()-sizeof (quint16); tcpclient-> write (Block);} void client: readmessage () {qdatastream in (tcpclient); In. setversion (qdatastream: qt_4_0); If (blocksize = 0) {If (tcpclient-> bytesavailable () <(INT) sizeof (quint16) return; in> blocksize;} If (tcpclient-> bytesavailable () <blocksize) return; In> readstring; label-> settext (readstring);} void client :: displayerror (q1_actsocket: socketerror) {Switch (socketerror) {Case q1_actsocket: remotehostclosederror: break; Case q1_actsocket: hostnotfounderror: qmessagebox: Information (this, TR ("Fortune client"), TR ("the host was not found. please check the "" host name and port settings. "); break; Case qiniactsocket: connectionrefusederror: qmessagebox: Information (this, TR (" Fortune client "), TR (" the connection was refused by the peer. "" Make sure the fortune server is running, "" and check that the host name and port "" settings are correct. "); break; default: qmessagebox: Information (this, TR (" Fortune client "), TR (" the following error occurred: % 1. "). arg (tcpclient-> errorstring () ;}// main. CPP # include "client. H "# include <qtgui/qapplication> int main (INT argc, char * argv []) {qapplication A (argc, argv); client W; W. show (); Return a.exe C ();}

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.