第10章:TcpServer
1,TCP服务端
2,源码:
#ifndef SERVER_H
#define SERVER_H
#include <QObject>
#include <QTcpServer>
#include <QList>
#include "tcpclientsocket.h"
class Server : public QTcpServer
{
Q_OBJECT
public:
Server(QObject *parent = 0, int port = 0);
QList<TcpClientSocket *> tcpClientSocketList; //用来保存与每一个客户端连接的TcpClientSocket;
signals:
void updateServer(QString, int);
public slots:
void updateClients(QString, int);
void slotDisconnected(int);
protected:
void incomingConnection(int socketDescriptor);
};
#endif // SERVER_H
#include "server.h"
Server::Server(QObject *parent, int port) :QTcpServer(parent)
{
//QHostAddress::Null //表示一个空地址
//QHostAddress::LocalHost //表示本地地址
//QHostAddress::Broadcast //表示广播地址255,255,255,255
//QHostAddress::Any //表示IPV4的任意地址0.0.0.0
//QHostAddress::AnyIPv6 //表示IPV6的任意地址
listen(QHostAddress::Any, port); //在指定的端口对任意地址进行监听
}
//当出现一个新的连接是,QTcpServer触发该函数,参数socketDescriptor指定了连接socket的描述符
void Server::incomingConnection(int socketDescriptor)
{
//创建一个新的TcpClientSocket与客户端通信
TcpClientSocket *tcpClientSocket = new TcpClientSocket(this);
//连接TcpClientSocket的updateClients信号
connect(tcpClientSocket, SIGNAL(updateClients(QString,int)), this, SLOT(updateClients(QString,int)));
//连接TcpClientSocket的disconnected信号
connect(tcpClientSocket, SIGNAL(disconnected(int)), this, SLOT(slotDisconnected(int)));
//将新创建的TcpClientSocket的套接字描述符指定为参数
tcpClientSocket->setSocketDescriptor(socketDescriptor);
tcpClientSocketList.append(tcpClientSocket);
}
//将任意客户端发来的信息进行广播,保证聊天室的所有客户均能看到其他人的发言
void Server::updateClients(QString msg, int length)
{
//发送updateServer信号,用来通知服务器对话框跟新相应的显示状态
emit updateServer(msg, length);
//实现信息的广播
for(int i=0; i<tcpClientSocketList.count(); i++)
{
QTcpSocket *item = tcpClientSocketList.at(i);
QString str = "Admin: Receive";
if (item->write(str.toLatin1(), str.length()) != length)
{
continue;
}
}
}
//断开TcpClientSocket对象删除的功能
void Server::slotDisconnected(int descriptor)
{
for (int i=0; i<tcpClientSocketList.count(); i++)
{
QTcpSocket *item = tcpClientSocketList.at(i);
if (item->socketDescriptor() == descriptor)
{
tcpClientSocketList.removeAt(i);
return;
}
}
return;
}
#ifndef TCPCLIENTSOCKET_H
#define TCPCLIENTSOCKET_H
#include <QObject>
#include <QTcpSocket>
class TcpClientSocket : public QTcpSocket
{
Q_OBJECT //创建信号和槽的关系
public:
TcpClientSocket(QObject *parent = 0);
signals:
void updateClients(QString, int);
void disconnected(int);
protected slots:
void dateReceived();
void slotDiscoonected();
};
#endif // TCPCLIENTSOCKET_H
#include "tcpclientsocket.h"
//建立关联
TcpClientSocket::TcpClientSocket(QObject *parent):QTcpSocket(parent)
{
connect(this, SIGNAL(readyRead()), this, SLOT(dateReceived()));
connect(this, SIGNAL(disconnected()), this, SLOT(slotDiscoonected()));
}
//数据接收
void TcpClientSocket::dateReceived()
{
while(bytesAvailable() > 0)
{
int length = bytesAvailable();
char buf[1024];
read(buf, length);
QString msg = buf;
emit updateClients(msg, length);
}
}
// 断开连接
void TcpClientSocket::slotDiscoonected()
{
emit disconnected(this->socketDescriptor());
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
port = 5555;
ui->lineEdit->setText(QString::number(port));
}
MainWindow::~MainWindow()
{
delete ui;
}
//创建聊天室
void MainWindow::on_pushButton_clicked()
{
server = new Server(this, port);
connect(server, SIGNAL(updateServer(QString,int)), this, SLOT(updateServer(QString,int)));
ui->pushButton->setEnabled(false);
}
//用于更新服务器上的信息显示
void MainWindow::updateServer(QString msg, int length)
{
ui->listWidget->addItem(msg.left(length));
}
3,效果: