刚接触 Qt 网络编程这一块,以下是一个简单的 tcp 通信流程,里面还有很多东西没有弄懂,难免有错误存在,在这里先做记录,以后弄懂了再做改正。
服务器端代码:
chat_server.h
#ifndef __chat_server_h__
#define __chat_server_h__
#include <QTcpServer>
class MySocket;
class ChatServer : public QTcpServer
{
Q_OBJECT
public:
ChatServer ( QObject *parent = NULL );
~ChatServer ();
void Run ( quint16 port );
protected:
void incomingConnection ( int handle );
private slots:
void clientDisconnected ();
private:
quint16 _port;
QList<MySocket*> _mysockets;
};
#endif // __chat_server_h__
chat_server.cpp
#include "chat_server.h"
#include "my_socket.h"
#include <QHostAddress>
ChatServer::ChatServer( QObject *parent /* = NULL */ )
: QTcpServer( parent )
{
_mysockets.empty();
}
ChatServer::~ChatServer()
{
qDeleteAll( _mysockets );
_mysockets.clear();
}
void ChatServer::Run( quint16 port )
{
if( !this->listen(QHostAddress::Any, port) )
printf( "ChatServer listen failed !" );
}
void ChatServer::incomingConnection( int handle )
{
printf( "incomingConnection(): %d !\n", handle );
MySocket *mysocket = new MySocket( this );
mysocket->setSocketDescriptor( handle );
connect( mysocket, SIGNAL(disconnected()), this, SLOT(clientDisconnected()) );
_mysockets.append( mysocket );
}
void ChatServer::clientDisconnected()
{
printf( "client disconnected !\n" );
QList<MySocket*>::iterator iter;
for( iter = _mysockets.begin(); iter != _mysockets.end(); iter++ ) {
if( -1 == (*iter)->socketDescriptor() ) {
_mysockets.erase( iter );
return;
}
}
}
my_socket.h
#ifndef __my_socket_h__
#define __my_socket_h__
#include <QThread>
#include <QTcpSocket>
class ChatServer;
class MySocket : public QTcpSocket
{
Q_OBJECT
public:
MySocket ( QObject *parent = NULL );
~MySocket ();
private slots:
void onReadyRead ();
};
#endif // __my_socket_h__
my_socket.cpp
#include "my_socket.h"
#include "chat_server.h"
#include <QTcpSocket>
MySocket::MySocket( QObject *parent /* = NULL */ )
: QTcpSocket( parent )
{
connect( this, SIGNAL(readyRead()), this, SLOT(onReadyRead()) );
}
MySocket::~MySocket()
{
printf( "~MySocket\n" );
close();
}
void MySocket::onReadyRead()
{
char data[1024] = { 0 };
int len = readData( data, 1024 );
if( len <= 0 ) {
printf( "MySocket::OnReadyRead() read data failed !\n" );
return;
}
printf( "receive data: %s\n", data );
if( 0 >= writeData(data, len) )
printf( "MySocket::OnReadyRead() write data failed !\n" );
else
printf( "send data: %s\n", data );
}
main.cpp
#include "chat_server.h"
#include <QtCore/QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ChatServer server;
server.Run( 33333 );
return a.exec();
}
客户端代码:
chat_client.h
#ifndef __chat_client_h__
#define __chat_client_h__
#include <QTcpSocket>
class ChatClient : public QTcpSocket
{
Q_OBJECT
public:
ChatClient ( QObject *parent = NULL );
~ChatClient ();
void ConnectToServer ( const char *ip, quint16 port );
void Close ();
bool WriteData ( const char *data, qint64 len );
protected:
void ParseData ( const char *data, qint64 len );
private slots:
void OnConnected ();
void OnReadyRead ();
private:
enum { BUFFERSIZE_MAX = 1024 };
};
#endif // __chat_client_h__
chat_client.cpp
#include "chat_client.h"
#include <QHostAddress>
ChatClient::ChatClient( QObject *parent /* = NULL */ )
: QTcpSocket( parent )
{
connect( this, SIGNAL(readyRead()), this, SLOT(OnReadyRead()) );
connect( this, SIGNAL(connected()), this, SLOT(OnConnected()) );
}
ChatClient::~ChatClient()
{
}
void ChatClient::ConnectToServer( const char *ip, quint16 port )
{
QString strip( ip );
QHostAddress addr;
addr.setAddress( strip );
connectToHost( addr, port );
}
void ChatClient::Close()
{
disconnectFromHost();
close();
}
bool ChatClient::WriteData( const char *data, qint64 len )
{
if( NULL == data || len <= 0 )
return false;
qint64 ret = writeData( data, len );
if( 0 >= ret )
return false;
waitForBytesWritten( -1 ); // why ?
printf( "send data: %s\n", data );
waitForReadyRead( -1 ); // why ?
return true;
}
void ChatClient::ParseData( const char *data, qint64 len )
{
printf( "receive data: %s\n", data );
}
void ChatClient::OnReadyRead()
{
char data[BUFFERSIZE_MAX] = { 0 };
qint64 len = readData( data, BUFFERSIZE_MAX );
if( len <= 0 )
return;
else
ParseData( data, len );
}
void ChatClient::OnConnected()
{
printf( "connected: %d !\n", socketDescriptor() );
}
main.cpp
#include "chat_client.h"
#include <QtCore/QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ChatClient client;
char ip[16] = { 0 };
quint16 port = 0;
client.ConnectToServer( "127.0.0.1", 33333 );
client.waitForConnected( -1 );
char msg[1024] = { 0 };
printf( "please input message(exit with 'exit'): \n" );
while( 1 ) {
gets( msg );
if( 0 == strcmp(msg, "exit") )
break;
if( !client.WriteData(msg, strlen(msg) + 1) ) {
printf( "WriteData failed !\n" );
break;
}
}
client.Close();
return a.exec();
}
执行结果: