您的位置:首页 > 理论基础 > 计算机网络

Qt 简单的 tcp socket 通信流程

2011-09-22 14:12 567 查看
刚接触 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();
}


执行结果:





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: