qt_Qtcp

QTcpSocket QTcpServer

在这里插入图片描述

函数 作用
bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0) 监听
void setMaxPendingConnections(int numConnections) 可以挂起的连接数量
QHostAddress serverAddress() const 地址
quint16 serverPort() const 端口

signalls:
void acceptError(QAbstractSocket::SocketError socketError)
void newConnection()

先来个小例子
在这里插入图片描述

/*
* 大致的过程如下:
* m_tcpserver=new QTcpServer(this);
* m_tcpserver->listen(QHostAddress::Any,30142);//监听所有ip的端口
*connect(m_tcpserver,SIGNAL(newConnection()),this,SLOT(newConnect())); 
*  m_tcpsocket = m_tcpserver->nextPendingConnection(); //得到每个连进来的socket
* connect(m_tcpsocket,SIGNAL(readyRead()),this,SLOT(readMessage())); 
*  m_tcpsocket->write(strMesg.toUtf8()); //发送
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QPushButton>
#include<QTcpServer>
#include<QTcpSocket>
#include<QTextBrowser>
#include<QTextEdit>
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
public slots:
    void startTcpserver();
    void sendMessage();
    void newConnect();
    void readMessage();
private:
    QPushButton *start_bt,*send_bt;
    QTextEdit *input_edit;
    QTextBrowser *text_browser;
    QTcpServer *m_tcpserver;
    QTcpSocket *m_tcpsocket;

};

#endif // MAINWINDOW_H

#include "mainwindow.h"
#include<QDateTime>
#include<QAction>
#include<QHostAddress>
#include<QHBoxLayout>
#include<QVBoxLayout>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QWidget *wid=new QWidget;
    this->setCentralWidget(wid);
    QHBoxLayout *buttom_layout=new QHBoxLayout;
    QVBoxLayout *main_layout=new QVBoxLayout(wid);
    start_bt=new QPushButton("Start");
    send_bt=new QPushButton("Send");
    input_edit=new QTextEdit();
    text_browser=new QTextBrowser();
    buttom_layout->addStretch();
    buttom_layout->addWidget(start_bt);
    buttom_layout->addStretch();
    buttom_layout->addWidget(send_bt);
    buttom_layout->addStretch();
    buttom_layout->setSpacing(100);
    text_browser->setFixedHeight(300);
    main_layout->addWidget(text_browser);
    main_layout->addSpacing(30);
    input_edit->setFixedHeight(70);
    main_layout->addWidget(input_edit);
    main_layout->addSpacing(30);
    main_layout->addLayout(buttom_layout);
    main_layout->addStretch();
    main_layout->setContentsMargins(30,30,30,30);
    this->resize(500,500);
    this->setWindowTitle("My QQ Server");
    send_bt->setShortcut(Qt::Key_Enter);

    //=============以上为界面设置===========
    m_tcpserver=new QTcpServer(this);
    m_tcpsocket = new QTcpSocket;
    connect(start_bt,SIGNAL(clicked(bool)),this,SLOT(startTcpserver()));
    connect(send_bt,SIGNAL(clicked(bool)),this,SLOT(sendMessage()));
    this->show();


}

MainWindow::~MainWindow()
{

}
void  MainWindow::startTcpserver()
{
    m_tcpserver->listen(QHostAddress::Any,30142);//监听所有ip的端口30142
    qDebug()<<"start server";
    //新连接信号触发,调用newConnect()槽函数,这个跟信号函数一样,其实你可以随便取。
    connect(m_tcpserver,SIGNAL(newConnection()),this,SLOT(newConnect()));
}
void MainWindow::newConnect()
{
    m_tcpsocket = m_tcpserver->nextPendingConnection(); //得到每个连进来的socket
    qDebug()<<"new Connect";
    text_browser->append(QString("%0").arg(m_tcpsocket->peerAddress().toIPv4Address())+" is connected");
    connect(m_tcpsocket,SIGNAL(readyRead()),this,SLOT(readMessage())); //有可读的信息,触发读函数槽
}
void MainWindow::readMessage()
{
    QByteArray qba= m_tcpsocket->readAll(); //读取
    qDebug()<<qba;

    QString ss=QVariant(qba).toString();
    text_browser->append(QDateTime::currentDateTime().time().toString()+"\n"+ss);
}
void MainWindow::sendMessage()
{
    QString strMesg= input_edit->toPlainText();
    qDebug()<<strMesg;
    input_edit->clear();
    m_tcpsocket->write(strMesg.toUtf8()); //发送
    text_browser->append(QDateTime::currentDateTime().time().toString()+"\n"+strMesg);
}



#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QPushButton>
#include<QTextBrowser>
#include<QTcpSocket>
#include<QTextEdit>
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
public slots:
    void connectServer();
    void readMessage();
    void sendMessage();

private:
    QPushButton *start_bt,*send_bt;
    QTextEdit *input_edit;
    QTextBrowser *text_browser;
    QTcpSocket *m_tcpsocket;
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include<QAction>
#include<QDateTime>
#include<QHBoxLayout>
#include<QVBoxLayout>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QWidget *wid=new QWidget;
    this->setCentralWidget(wid);
    QHBoxLayout *buttom_layout=new QHBoxLayout;
    QVBoxLayout *main_layout=new QVBoxLayout(wid);
    start_bt=new QPushButton("Connect",wid);
    send_bt=new QPushButton("Send",wid);
    input_edit=new QTextEdit(wid);
    text_browser=new QTextBrowser(wid);
    buttom_layout->addStretch();
    buttom_layout->addWidget(start_bt);
    buttom_layout->addStretch();
    buttom_layout->addWidget(send_bt);
    buttom_layout->addStretch();
    buttom_layout->setSpacing(100);
    text_browser->setFixedHeight(300);
    main_layout->addWidget(text_browser);
    main_layout->addSpacing(30);
    input_edit->setFixedHeight(70);
    main_layout->addWidget(input_edit);
    main_layout->addSpacing(30);
    main_layout->addLayout(buttom_layout);
    main_layout->addStretch();
    main_layout->setContentsMargins(30,30,30,30);
    this->resize(500,500);
    m_tcpsocket = new QTcpSocket;
    this->setWindowTitle("My QQ client");
    send_bt->setShortcut(Qt::Key_Enter);

    connect(start_bt,SIGNAL(clicked(bool)),this,SLOT(connectServer()));
    connect(send_bt,SIGNAL(clicked(bool)),this,SLOT(sendMessage()));

}

MainWindow::~MainWindow()
{
}
void MainWindow::connectServer()
{
    m_tcpsocket=new QTcpSocket(this);
    m_tcpsocket->abort();
    m_tcpsocket->connectToHost("192.168.252.128",30142);
    connect(m_tcpsocket,SIGNAL(readyRead()),this,SLOT(readMessage()));
}
void MainWindow::readMessage()
{
    QByteArray qba =m_tcpsocket->readAll();
    qDebug()<<qba;
    QString ss=QVariant(qba).toString();
    text_browser->append(QDateTime::currentDateTime().time().toString()+"\n"+ss);

}
void MainWindow::sendMessage()
{
    QString ss= input_edit->toPlainText();
    m_tcpsocket->write(ss.toStdString().c_str(),strlen(ss.toStdString().c_str()));
    text_browser->append(QDateTime::currentDateTime().time().toString()+"\n"+ss);
    input_edit->clear();
}

完整代码下载:https://download.csdn.net/download/qq_33564134/10849077
Tcp聊天室服务器构造
在这里插入图片描述
构造原理

/*
 * ChatServer 构造原理
 * 1.服务器界面有ChatServer构成,他有一个tecserver保证了服务器的启动(startServer()),同时服务器需要更新显示,
 * 有了updateBrowser(QString msg,int)
 * 2.服务器的启动,由TcpServer构成,他拥有
 * (1)sendMsg(QString,int)给全部的tcpsocket发送信息同时发送信号void updateBrowser(QString msg,int)
 * 给ChatServer 提醒更新界面
 * (2)void socketDisconnect(int)去移除相关的tcpsocket
 * (3)void incomingConnection(qintptr socketDescriptor)处理tcpsocket的接入
 * 3.tcpsocket重构信号
 * connect(this,SIGNAL(readyRead()),this,SLOT(receiveMsg()));//更改信号
 * connect(this,SIGNAL(disconnected()),this,SLOT(socketDisconnect()));//更改信号
 * (1)在receiveMsg()里面接收了msg,emit emit sendMsg(msg,len),此信号会被tcpserver接收到,然后群发信息
 *(2)socketDisconnect() 将会给tcpserver一个socketDesconnect(this->socketDescriptor())的信号
*/

在这里插入图片描述

//chatserner.h
#ifndef CHATSERNER_H
#define CHATSERNER_H

#include<QListWidget>
#include<QLabel>
#include<QLineEdit>
#include<QPushButton>
#include <QWidget>
#include<QGridLayout>
#include<QString>
#include"tcpserver.h"
/*
 * ChatServer 构造原理
 * 1.服务器界面有ChatServer构成,他有一个tecserver保证了服务器的启动(startServer()),同时服务器需要更新显示,
 * 有了updateBrowser(QString msg,int)
 * 2.服务器的启动,由TcpServer构成,他拥有
 * (1)sendMsg(QString,int)给全部的tcpsocket发送信息同时发送信号void updateBrowser(QString msg,int)
 * 给ChatServer 提醒更新界面
 * (2)void socketDisconnect(int)去移除相关的tcpsocket
 * (3)void incomingConnection(qintptr socketDescriptor)处理tcpsocket的接入
 * 3.tcpsocket重构信号
 * connect(this,SIGNAL(readyRead()),this,SLOT(receiveMsg()));//更改信号
 * connect(this,SIGNAL(disconnected()),this,SLOT(socketDisconnect()));//更改信号
 * (1)在receiveMsg()里面接收了msg,emit emit sendMsg(msg,len),此信号会被tcpserver接收到,然后群发信息
 *(2)socketDisconnect() 将会给tcpserver一个socketDesconnect(this->socketDescriptor())的信号
 * 
 * 此文件用于界面的编写,然后调用自己重构的tcpserver进来
*/
class ChatSerner : public QWidget
{
    Q_OBJECT

public:
    ChatSerner(QWidget *parent = 0);
    ~ChatSerner();
    void initWidget();                      //初始化界面
public slots:
    void startServer();                     //当creat_bt点击时候调用,目的是创建QTcpServer
    void updateBrowser(QString msg,int);    //当socket有信息传递时候,更新服务器的显示
private:
    QListWidget *server_widget;
    QLabel *port_label;
    QLineEdit *m_port;
    QPushButton *creat_bt;
    QGridLayout *main_layout;
    TcpServer *tcp_server;
};

#endif // CHATSERNER_H

//chatserner.cpp
#include "chatserner.h"
#include<QDebug>

ChatSerner::ChatSerner(QWidget *parent)
    : QWidget(parent)
{
    initWidget();
}

ChatSerner::~ChatSerner()
{

}
void ChatSerner::initWidget()
{
    setWindowTitle("TCP Server");
    server_widget = new QListWidget;
    port_label = new QLabel("接听端口:");
    m_port = new QLineEdit;
    m_port->setText("30142");
    creat_bt = new QPushButton("创建聊天室");
    main_layout = new QGridLayout(this);
    main_layout->addWidget(server_widget,0,0,1,2);
    main_layout->addWidget(port_label,1,0);
    main_layout->addWidget(m_port,1,1);
    main_layout->addWidget(creat_bt,2,0,1,2);
    resize(400,400);
    connect(creat_bt,SIGNAL(clicked(bool)),this,SLOT(startServer()));
}
void ChatSerner::startServer()//启动服务器
{
    int port=m_port->text().toInt();
    qDebug()<<"server start runing..."<<port;
    //启动了服务器,接收请求交给tcp_server的 incomingCo....
    tcp_server=new TcpServer(this,port);
    //更新了服务器的显示界面
    connect(tcp_server,SIGNAL(updateBrowser(QString,int)),this,SLOT(updateBrowser(QString,int)));
    creat_bt->setEnabled(false);
}
void ChatSerner::updateBrowser(QString msg,int len)
{
    server_widget->addItem(msg.left(len));
}



//tcpserver.h
#ifndef TCPSERVER_H
#define TCPSERVER_H

#include<QTcpServer>
#include"tcpsocket.h"
/*
 * tcpserver 这个文件重构qtcpserver的信号,加入了QList<>这样保证了多个socket的开通
*/
class TcpServer:public QTcpServer
{
    Q_OBJECT
public:
    TcpServer(QObject *parent=0,int port=0);
    QList<TcpSocket*> socket_list;                      //socket的list
signals:
    void updateBrowser(QString msg,int);                //发送个信号给服务器,更新显示界面
public slots:
    void sendMsg(QString,int);                          //发送信息给客户端
    void socketDisconnect(int);                         //发生了socket的退出
protected:
    void incomingConnection(qintptr socketDescriptor);  //socket的接入
};

#endif // TCPSERVER_H



//tcpserver.cpp
#include "tcpserver.h"
#include<QHostAddress>
int i=1;
TcpServer::TcpServer(QObject *parent,int port):QTcpServer(parent)
{
    listen(QHostAddress::Any,port);//监听任何ip的请求
    qDebug()<<"listen ....";
}
void TcpServer::incomingConnection(qintptr socketDescriptor)
{
    qDebug()<<"incomingConnection"<<i;
    TcpSocket *tcpsocket=new TcpSocket(this);
    connect(tcpsocket,SIGNAL(sendMsg(QString,int)),this,SLOT(sendMsg(QString,int)));
    connect(tcpsocket,SIGNAL(socketDesconnect(int)),this,SLOT(socketDisconnect(int)));
    tcpsocket->setSocketDescriptor(socketDescriptor);
    socket_list.append(tcpsocket);
    i++;

}
void TcpServer::sendMsg(QString msg, int len)
{
    emit updateBrowser(msg,len);//更新服务器的显示
    for(int i=0;i<socket_list.count();i++)
        {
            QTcpSocket *item = socket_list.at(i);
            if(item->write(msg.toLatin1(),len)!=len)
            {
                continue;
            }
        }
}
void TcpServer::socketDisconnect(int socketDescriptor)
{
    for(int i=0;i<socket_list.count();i++)
    {
        QTcpSocket *item=socket_list.at(i);
        if(item->socketDescriptor()==socketDescriptor)
        {
            socket_list.removeAt(i);
        }
    }
}

//tcpsocket.h
#ifndef TCPSOCKET_H
#define TCPSOCKET_H
#include<QTcpSocket>
/*
 * 主要是完成信号的转换,用于接收客户端的信息
*/
class TcpSocket:public QTcpSocket
{
    Q_OBJECT
public:
    TcpSocket(QObject *parent=0);
public slots:
    void receiveMsg();//接收客户端的信息
    void socketDisconnect();//socket关闭
signals:
    void sendMsg(QString,int);
    void socketDesconnect(int);
};

#endif // TCPSOCKET_H



//tcpsocket.cpp
#include "tcpsocket.h"

TcpSocket::TcpSocket(QObject *parent)
{
    qDebug()<<"socket create...";
    connect(this,SIGNAL(readyRead()),this,SLOT(receiveMsg()));//更改信号
    connect(this,SIGNAL(disconnected()),this,SLOT(socketDisconnect()));//更改信号
}
void TcpSocket::receiveMsg()
{
    while(bytesAvailable()>0)//qtcpsocket自带的函数
    {
        int len=bytesAvailable();
        char buf[1024];
        read(buf,len);
        QString msg=buf;
        emit sendMsg(msg,len);
    }
}
void TcpSocket::socketDisconnect()
{
    emit socketDesconnect(this->socketDescriptor());
}

//客户端
#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QDialog>
#include <QListWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QLabel>
#include <QGridLayout>
#include <QHostAddress>
#include <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("发送"));

    userNameLabel = new QLabel(tr("用户名:"));
    userNameLineEdit = new QLineEdit;
    userNameLineEdit->setText("zz");

    serverIPLabel = new QLabel(tr("服务器地址:"));
    serverIPLineEdit = new QLineEdit;
    serverIPLineEdit->setText("192.169.252.128");

    portLabel = new QLabel(tr("端口:"));
    portLineEdit = new QLineEdit;
    portLineEdit->setText("30142");

    enterBtn= new QPushButton(tr("进入聊天室"));

    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 = 30142;
    portLineEdit->setText(QString::number(port));

//    serverIP =new QHostAddress(QHostAddress::Any);
    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("192.168.252.128"))
        {
            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("进入聊天室"));
}

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()).toUtf8());
    }
}

完整代码下载:
https://download.csdn.net/download/qq_33564134/10851675

猜你喜欢

转载自blog.csdn.net/qq_33564134/article/details/84992922
QT