QT网络编程Tcp下C/S架构的即时通信实例

先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面。

#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QDialog>
#include <QListWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QGridLayout>
#include <QtNetWork/QHostAddress>
#include <QtNetWork/QTcpSocket>

class TcpClient : public QDialog
{
 Q_OBJECT

public:
 TcpClient(QWidget *parent = 0,Qt::WindowFlags f=0);
 ~TcpClient();
private:
 QListWidget *contentListWidget;
 QLineEdit *sendLineEdit;
 QPushButton *sendBtn;
 QLabel *userNameLabel;
 QLineEdit *userNameLineEdit;
 QLabel *serverIPLabel;
 QLineEdit *serverIPLineEdit;
 QLabel *portLabel;
 QLineEdit *portLineEdit;
 QPushButton *enterBtn;
 QGridLayout *mainLayout;
 bool status;
 int port;
 QHostAddress *serverIP;
 QString userName;
 QTcpSocket *tcpSocket;
public slots:
 void slotEnter();
 void slotConnected();
 void slotDisconnected();
 void dataReceived();
 void slotSend();
};

#endif // TCPCLIENT_H

有一个加入服务器的按钮,还有一个发送消息的按钮,在头文件,先定义两个函数。

#include "tcpclient.h"
#include <QMessageBox>
#include <QHostInfo>

TcpClient::TcpClient(QWidget *parent,Qt::WindowFlags f)
 : QDialog(parent,f)
{
 setWindowTitle(tr("TCP Client"));

 contentListWidget = new QListWidget;

 sendLineEdit = new QLineEdit;
 sendBtn = new QPushButton(tr("send"));

 userNameLabel = new QLabel(tr("name"));
 userNameLineEdit = new QLineEdit;

 serverIPLabel = new QLabel(tr("server"));
 serverIPLineEdit = new QLineEdit;

 portLabel = new QLabel(tr("port"));
 portLineEdit = new QLineEdit;

 enterBtn= new QPushButton(tr("join chat"));

 mainLayout = new QGridLayout(this);
 mainLayout->addWidget(contentListWidget,0,0,1,2);
 mainLayout->addWidget(sendLineEdit,1,0);
 mainLayout->addWidget(sendBtn,1,1);
 mainLayout->addWidget(userNameLabel,2,0);
 mainLayout->addWidget(userNameLineEdit,2,1);
 mainLayout->addWidget(serverIPLabel,3,0);
 mainLayout->addWidget(serverIPLineEdit,3,1);
 mainLayout->addWidget(portLabel,4,0);
 mainLayout->addWidget(portLineEdit,4,1);
 mainLayout->addWidget(enterBtn,5,0,1,2);

 status = false;

 port = 8010;
 portLineEdit->setText(QString::number(port));

 serverIP =new QHostAddress();

 connect(enterBtn,SIGNAL(clicked()),this,SLOT(slotEnter()));
 connect(sendBtn,SIGNAL(clicked()),this,SLOT(slotSend()));

 sendBtn->setEnabled(false);
}

TcpClient::~TcpClient()
{

}

void TcpClient::slotEnter()
{
 if(!status)
 {
  QString ip = serverIPLineEdit->text();
  if(!serverIP->setAddress(ip))
  {
   QMessageBox::information(this,tr("error"),tr("server ip address error!"));
   return;
  }

  if(userNameLineEdit->text()=="")
  {
   QMessageBox::information(this,tr("error"),tr("User name error!"));
   return;
  }

  userName=userNameLineEdit->text();

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

  tcpSocket->connectToHost(*serverIP,port);

  status=true;
 }
 else
 {
  int length=0;
  QString msg=userName+tr(":Leave Chat Room");
  if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg. length())
  {
   return;
  }

  tcpSocket->disconnectFromHost();

  status=false;
 }
}

void TcpClient::slotConnected()
{
 sendBtn->setEnabled(true);
 enterBtn->setText(tr("离开"));

 int length=0;
 QString msg=userName+tr(":Enter Chat Room");
 if((length=tcpSocket->write(msg.toLatin1(),msg.length()))!=msg.length())
 {
  return;
 }
}

void TcpClient::slotSend()
{
 if(sendLineEdit->text()=="")
 {
  return ;
 }

 QString msg=userName+":"+sendLineEdit->text();

 tcpSocket->write(msg.toLatin1(),msg.length());
 sendLineEdit->clear();
}

void TcpClient::slotDisconnected()
{
 sendBtn->setEnabled(false);
 enterBtn->setText(tr("join chat"));
}

void TcpClient::dataReceived()
{
 while(tcpSocket->bytesAvailable()>0)
 {
  QByteArray datagram;
  datagram.resize(tcpSocket->bytesAvailable());

  tcpSocket->read(datagram.data(),datagram.size());

  QString msg=datagram.data();
  contentListWidget->addItem(msg.left(datagram.size()));
 }
}

实现界面布局。在Enter槽函数中,确定加入还是离开的服务器的功能。如果加入了,就将消息,写到tcpsocket中,构造消。

服务端的头文件:

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QDialog>
#include <QListWidget>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QGridLayout>
#include "server.h"

class TcpServer : public QDialog
{
 Q_OBJECT

public:
 TcpServer(QWidget *parent = 0,Qt::WindowFlags f=0);
 ~TcpServer();
private:
 QListWidget *ContentListWidget;
 QLabel *PortLabel;
 QLineEdit *PortLineEdit;
 QPushButton *CreateBtn;
 QGridLayout *mainLayout;
 int port;
 Server *server;
public slots:
 void slotCreateServer();
 void updateServer(QString,int);
};

#endif // TCPSERVER_H

这是服务端的界面的,把消息显示而已。实现这个布局。

#include "tcpserver.h"

TcpServer::TcpServer(QWidget *parent,Qt::WindowFlags f)
 : QDialog(parent,f)
{
 setWindowTitle(tr("TCP Server"));

 ContentListWidget = new QListWidget;

 PortLabel = new QLabel(tr(" port"));
 PortLineEdit = new QLineEdit;

 CreateBtn = new QPushButton(tr("create chat"));
 mainLayout = new QGridLayout(this);
 mainLayout->addWidget(ContentListWidget,0,0,1,2);
 mainLayout->addWidget(PortLabel,1,0);
 mainLayout->addWidget(PortLineEdit,1,1);
 mainLayout->addWidget(CreateBtn,2,0,1,2);

 port=8010;
 PortLineEdit->setText(QString::number(port));

 connect(CreateBtn,SIGNAL(clicked()),this,SLOT(slotCreateServer()));
}

TcpServer::~TcpServer()
{

}

void TcpServer::slotCreateServer()
{
 server = new Server(this,port);
 connect(server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));

 CreateBtn->setEnabled(false);
}

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

创建TCP的套接字,以便实现服务端和客户端的通信。

#ifndef TCPCLIENTSOCKET_H
#define TCPCLIENTSOCKET_H

#include <QtNetWork/QTcpSocket>
#include <QObject>

class TcpClientSocket : public QTcpSocket
{
 Q_OBJECT
public:
 TcpClientSocket();
signals:
 void updateClients(QString,int);
 void disconnected(int);
protected slots:
 void dataReceived();
 void slotDisconnected();
};

#endif // TCPCLIENTSOCKET_H

以上是头文件,具体的是:

#include "tcpclientsocket.h"

TcpClientSocket::TcpClientSocket()
{
 connect(this,SIGNAL(readyRead()),this,SLOT(dataReceived()));
 connect(this,SIGNAL(disconnected()),this,SLOT(slotDisconnected()));
}

void TcpClientSocket::dataReceived()
{
 while(bytesAvailable()>0)
 {
  int length = bytesAvailable();
  char buf[1024];
  read(buf,length);

  QString msg=buf;
  emit updateClients(msg,length);
 }
}

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

实现服务器,头文件:

#ifndef SERVER_H
#define SERVER_H

#include <QtNetWork/QTcpServer>
#include <QObject>
#include "tcpclientsocket.h"

class Server : public QTcpServer
{
 Q_OBJECT
public:
 Server(QObject *parent=0,int port=0);
 QList<TcpClientSocket*> tcpClientSocketList;
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)
{
 listen(QHostAddress::Any,port);
}

void Server::incomingConnection(int socketDescriptor)
{
 TcpClientSocket *tcpClientSocket = new TcpClientSocket;
 connect(tcpClientSocket,SIGNAL(updateClients(QString,int)),this,SLOT(updateClients(QString,int)));
 connect(tcpClientSocket,SIGNAL(disconnected(int)),this,SLOT(slotDisconnected(int)));

 tcpClientSocket->setSocketDescriptor(socketDescriptor);

 tcpClientSocketList.append(tcpClientSocket);
}

void Server::updateClients(QString msg,int length)
{
 emit updateServer(msg,length);
 for(int i=0;i<tcpClientSocketList.count();i++)
 {
  QTcpSocket *item = tcpClientSocketList.at(i);
  if(item->write(msg.toLatin1(),length)!=length)
  {
   continue;
  }
 }
}

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;
}

实现后的界面:

以上这篇QT网络编程Tcp下C/S架构的即时通信实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • QT网络编程UDP下C/S架构广播通信(实例讲解)

    QT有封装好的UDP协议的类,QUdpSocket,里面有我们想要的函数接口.感兴趣的话,可以看看. 先搞服务端吧,写一个子类,继承QDialog类,起名为UdpServer类.头文件要引用我们上边说的QUdpSocket这个类,还有我们想要的布局的类. #ifndef UDPSERVER_H #define UDPSERVER_H #include <QDialog> #include <QLabel> #include <QLineEdit> #include &l

  • QT网络编程Tcp下C/S架构的即时通信实例

    先写一个客户端,实现简单的,能加入聊天,以及加入服务器的界面. #ifndef TCPCLIENT_H #define TCPCLIENT_H #include <QDialog> #include <QListWidget> #include <QLineEdit> #include <QPushButton> #include <QLabel> #include <QGridLayout> #include <QtNetWo

  • 详解C# 网络编程系列:实现类似QQ的即时通信程序

    引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例来让大家更好的理解它们的工作原理以及怎样.Net类库去实现它们的.为了让大家更好的理解我们平常中常见的软件QQ的工作原理,所以在本专题中将利用前面专题介绍的知识来实现一个类似QQ的聊天程序.  一.即时通信系统 在我们的生活中经常使用即时通信的软件,我们经常接触到的有:QQ.阿里旺旺.MSN等等.这些都是属于即时通信(Instant Messenger,IM)软件,IM是指所有能够即时发送和接收互联网消息的软件. 在前面专题

  • Qt网络编程实现TCP通信

    Qt网络编程实现TCP通信,供大家参考,具体内容如下 标签(空格分隔): Tcp通信 一.Tcp简介 (1)TCP(Transmission Control Protocol,传输控制协议)TCP是一个用于数据传输的传输层网络协议,多个网络协议包括(HTTP和FTP都是基于TCP协议),TCP是面向数据流和连接的可靠的传输协议,它区别于传输层的另外一个协议UDP(具体可看—Qt简单实现UDP通信) . (2)QTcpSocket继承自QAbstractSocket,与QUdpSocket传输的数

  • Java网络编程TCP实现文件上传功能

    本文实例为大家分享了Java网络编程TCP实现文件上传的具体代码,供大家参考,具体内容如下 上一篇博客,用网络编程TCP 实现聊天,这次实现文件上传. 客户端: package com.kuang.lesson02; import java.io.*; import java.net.InetAddress; import java.net.Socket; //客户端 public class TcpClientDemo2 { public static void main(String[] a

  • 老生常谈Java网络编程TCP通信(必看篇)

    Socket简介: Socket称为"套接字",描述IP地址和端口.在Internet上的主机一般运行多个服务软件,同时提供几种服务,每种服务都打开一个Socket,并绑定在一个端口上,不同的端口对应于不同的服务.Socket和ServerSocket类位于java.net包中.ServerSocket用于服务端,Socket是建立网络连接时使用的.连接成功时,应用程序两端都会产生一个Socket实例,通过操作这个实例完成所需会话. Socket常用方法: -int getLocalP

  • Java网络编程TCP实现聊天功能

    网络编程TCP实现聊天的前提还需要掌握IO流,话不多说,直接上代码! 客户端: package com.kuang.lesson02; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; //客户端 public class TcpClientDemo01 { public static void main(String[] ar

  • Python socket网络编程TCP/IP服务器与客户端通信

    Python socket网络编程 初学 python,前段时间买了两本书<python 编程从入门到实践><Python 核心编程第三版>,第一本书主要讲的是一些基本语法和一些基本的使用方法,而第二本则深入很多,自己看来也是一知半解,刚好看到了这部分网络编程,依然有好多不太理解的地方,不过想来通过自己不断的摸索,不断地搜寻资料学习,早晚应该会变得通透吧....... 这部分主要使用的模块就是 socket 模块,在这个模块中可以找到 socket()函数,该函数用于创建套接字对象

  • C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨

    1.TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,也有许多的企业应用和互联网应用.http协议在应用层运行. 02,传输层(Tanspot):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而TCP提供传输保证. 03,网络层(Netwok):网络层协议由一系列协议组成,包括ICMP.IGMP.RIP.OSPF.IP(v4,v6)等. 04,链路层(Link):又称为物

  • Qt中网络编程的实现

    目录 一.tcp/IP协议簇与udp 1.TCP/IP协议族 2.udp 3.常用的通讯协议小结 二.Qt中的tcp(这里只展示代码) 1.tcpsever 2.tcpclient 三.QT中的Udp 由于我没有系统的分享一些简单的计算机网络有关的,下面只是简单讲讲tcp/ip协议簇和udp 一.tcp/IP协议簇与udp 1.TCP/IP协议族 TCP/IP实际上是一个协同工作的通信家族,为网络通信提供通路.为方便讨论TCP/IP协议族,大体上分为三部分: ①.Internet协议(IP).

随机推荐