QT聊天室

使用Qt库中的 <QTcpServer>  和<QTcpSocket>类实现局域网络下的聊天室。

分为服务端和客户端;

服务端接收来自各个客户端的信息,并发送到所有客户端;

客户端用于用户登陆及聊天。

客户端:

使用<QTcpSocket>类即可;

首先在 工程文件.pro中加入一行:

QT       += network

创建工程,然后用一个dialog实现主窗体就行了;

用Qt设计器添加控件:

以下是Dialog.h源码:

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QTcpSocket>
#include <QHostAddress>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
  Q_OBJECT

public:
  explicit Dialog(QWidget *parent = 0);
  ~Dialog();

private:
  Ui::Dialog *ui;

  bool connectStatus;
  //
  int port;
  QHostAddress *serverIP;
  QString userName;
  QTcpSocket *tcpSocket;

public slots:
  void slotEnter();
  void slotConnected();
  void slotDisconnected();
  void slotDataReceived();
  void slotSend();
};

#endif // DIALOG_H

以下是Dialog.cpp源码:

#include "dialog.h"
#include "ui_dialog.h"

#include <QMessageBox>
#include <QHostAddress>

Dialog::Dialog(QWidget *parent) :
  QDialog(parent),
  ui(new Ui::Dialog)
{
  ui->setupUi(this);
  this->setFixedSize(400,500);
  this->setWindowTitle("TCP Client");

  ui->portLineEdit->setText("45454");
  ui->userNameLineEdit->setText("UserName");

  connect(ui->enterButton,SIGNAL(clicked()),this,SLOT(slotEnter()));
  connect(ui->sendButton,SIGNAL(clicked()),this,SLOT(slotSend()));

  this->serverIP = new QHostAddress();
  this->connectStatus = false;
  ui->sendButton->setEnabled(false);
}

Dialog::~Dialog()
{
  delete ui;
}

void Dialog::slotEnter()
{
  if(!this->connectStatus)
  {
    //---------------------------------------------------
    if(ui->userNameLineEdit->text()=="")
    {
      QMessageBox::information(this,tr("error"),tr("User name Error ! "));
    }
    this->userName = ui->userNameLineEdit->text();

    if(ui->serverIPLineEdit->text()=="")
    {
      QMessageBox::information(this,tr("error"),tr("Server Address Error ! "));
    }
    this->serverIP->setAddress(ui->serverIPLineEdit->text());

    if(ui->portLineEdit->text() == "")
    {
      QMessageBox::information(this,tr("error"),tr("Port Error ! "));
    }
    this->port = ui->portLineEdit->text().toInt();
    //---------------------------------------------------

    this->tcpSocket = new QTcpSocket(this);
    connect(this->tcpSocket,SIGNAL(connected()),this,SLOT(slotConnected()));
    connect(this->tcpSocket,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));

    this->tcpSocket->connectToHost(*this->serverIP,this->port); //
  }
  else
  {
    QString msg = this->userName + tr(":leave chat Room");
    this->tcpSocket->write(msg.toLatin1(),msg.length());

    this->tcpSocket->disconnectFromHost();
  }
}

void Dialog::slotConnected()
{
  ui->sendButton->setEnabled(true);
  ui->enterButton->setText(tr("Leave"));
  connect(this->tcpSocket,SIGNAL(readyRead()),this,SLOT(slotDataReceived()));

  QString msg = this->userName + tr(":Enter Chat room");
  this->tcpSocket->write(msg.toLatin1(),msg.length());
  this->connectStatus = true;
  QMessageBox::information(this,tr("Connected"),tr("Entered the Chat room"));
}

void Dialog::slotDisconnected()
{
  ui->sendButton->setEnabled(false);
  ui->enterButton->setText(tr("Enter"));
  this->connectStatus = false;

  QMessageBox::information(this,tr("Disconnected"),tr("Exited the Chat room"));
}

void Dialog::slotSend()
{
  if(ui->sendLineEdit->text()=="")
  {
    return;
  }
  QString msg = this->userName+" : "+ui->sendLineEdit->text();
  this->tcpSocket->write(msg.toLatin1(),msg.length());
  ui->sendLineEdit->clear();
}

void Dialog::slotDataReceived()
{
  while(tcpSocket->bytesAvailable()>0)
  {
    QString msg = this->tcpSocket->readAll();
    ui->contentListWidget->addItem(msg.left(msg.length()));
  }
}

然后是服务端:

同样,首先在 工程文件.pro中加入一行:

QT       += network

用Widgets实现主窗体:

服务端实现了两个类:<clientTCPsocket>类和<TCPserver>类,分别继承自<QTcpSocket><QTcpServer>;


clientTCPsocket.h:
#ifndef CLIENTTCPSOCKET_H
#define CLIENTTCPSOCKET_H

#include <QTcpSocket>
#include <QObject>

class clientTCPsocket : public QTcpSocket
{
  Q_OBJECT
public:
  clientTCPsocket(QObject *parent = 0);

signals:
  void updateClients(QString,int);
  void disconnected(int);

public slots:
  void dataReceived();
  void slotDisconnected();

};

#endif // CLIENTTCPSOCKET_H

clientTCPsocket.cpp:

#include "clienttcpsocket.h"

clientTCPsocket::clientTCPsocket(QObject *parent) :
  QTcpSocket(parent)
{
  connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));
  connect(this,SIGNAL(disconnected(int)),this,SLOT(slotDisconnected()));
}

void clientTCPsocket::dataReceived()
{
  while(this->bytesAvailable()>0)
  {
    QString msg = this->readAll();
    int length = msg.length();
    emit updateClients(msg,length);
  }
}

void clientTCPsocket::slotDisconnected()
{
  emit disconnected(this->socketDescriptor()); //
}

TCPserver.h:

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QObject>
#include <clienttcpsocket.h>

class TCPserver : public QTcpServer
{
  Q_OBJECT
public:
  TCPserver(QObject *parent = 0,int port = 0);
  QList<clientTCPsocket*>clientTCPsocketList;

signals:
  void updateServer(QString,int);

public slots:
  void updateClients(QString msg, int length);
  void slotDisconnected(int descriptor);
  void acceptConnection();

};

#endif // TCPSERVER_H

TCPserver.cpp:

#include "tcpserver.h"


TCPserver::TCPserver(QObject *parent,int port) :
  QTcpServer(parent)
{
  this->listen(QHostAddress::Any,port);
  connect(this,SIGNAL(newConnection()),this,SLOT(acceptConnection()));
}

void TCPserver::acceptConnection()
{
  clientTCPsocket *TCPsocket = new clientTCPsocket(this);
  connect(TCPsocket,SIGNAL(updateClients(QString,int)),this,SLOT(updateClients(QString,int)));
  connect(TCPsocket,SIGNAL(disconnected(int)),this,SLOT(slotDisconnected(int)));
  TCPsocket->setSocketDescriptor(this->nextPendingConnection()->socketDescriptor());
  this->clientTCPsocketList.append(TCPsocket);
}

void TCPserver::updateClients(QString msg, int length)
{
  emit updateServer(msg,length);							  //
  for(int i=0;i<clientTCPsocketList.count();i++)
  {
    QTcpSocket *item = clientTCPsocketList.at(i);
    item->write(msg.toLatin1(),length);
  }
}

void TCPserver::slotDisconnected(int descriptor)
{
  for(int i =0;i<clientTCPsocketList.count();i++)
  {
    QTcpSocket *item = clientTCPsocketList.at(i);
    if(item->socketDescriptor()==descriptor)
    {
      clientTCPsocketList.removeAt(i);
      return;
    }
  }
  return;
}

Widgets中创建并初始化一个TCPserver对象;

widgets.h:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <tcpserver.h>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
  Q_OBJECT

public:
  explicit Widget(QWidget *parent = 0);
  ~Widget();

private:
  Ui::Widget *ui;

  int port;
  TCPserver *server;

public slots:
    void slotCreateServer();
    void updateServer(QString msg, int length);
};

#endif // WIDGET_H

widgets.cpp:

#include "widget.h"
#include "ui_widget.h"

#include <QMessageBox>

Widget::Widget(QWidget *parent) :
  QWidget(parent),
  ui(new Ui::Widget)
{
  ui->setupUi(this);
  setWindowTitle(tr("TCP server"));
  this->setFixedSize(400,500);

  ui->PortlLineEdit->setText("45454");
  connect(ui->CreateBtn,SIGNAL(clicked()),this,SLOT(slotCreateServer()));

}

Widget::~Widget()
{
  delete ui;
}

void Widget::slotCreateServer()
{
  //*******************************************
  if(ui->PortlLineEdit->text() == "")
  {
    QMessageBox::information(this,tr("error"),tr("Port Error ! "));
  }
  this->port = ui->PortlLineEdit->text().toInt();
  //*******************************************

  this->server = new TCPserver(this,this->port);
  connect(this->server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));
  ui->CreateBtn->setEnabled(false);
}

void Widget::updateServer(QString msg, int length)
{
  ui->ContentListWidget->addItem(msg.left(length));
}

这样服务端和客户端都实现完成;

运行效果:

服务端:

客户端:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值