自己写的 基于多线程和TCPserver类、TCPsocket的类
来源:互联网 发布:c 生命数组 编辑:程序博客网 时间:2024/06/05 23:54
sever类监听,来一个连接,就开辟一个线程.....还有其他的功能 自己看吧。接口什么的都给了。
#include "tcpseverui.h"#include <QApplication>int main(int argc, char *argv[]){ QApplication a(argc, argv); TcpSeverUi w; w.show(); return a.exec();}#ifndef MYDEBUG_H#define MYDEBUG_H #define MYDEBUG #ifdef MYDEBUG #include<QDebug> #endif#endif // MYDEBUG_H#include "tcpclient.h"#include<QThread>tcpClient::tcpClient(qintptr handle, QObject *parent) : QTcpSocket(parent),handleback(handle){ connect(this,SIGNAL(disconnected()),this,SLOT(clientDisconnect())); connect(this,SIGNAL(readyRead()),this,SLOT(getMSg())); blocksize=0;}tcpClient::~tcpClient(){}void tcpClient::clientDisconnect(){ qDebug()<<"clientDisconnect 套接字"<<handleback; emit IWantToClose(handleback);}void tcpClient::serverToClientSlots(qintptr handle, const QByteArray &Blocks){ if(handle==handleback) { QByteArray send; QString t=Blocks; QDataStream out(&send,QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_3); out<<(quint64)(Blocks.size())<<t; qDebug()<<"客户线程:"<<QThread::currentThreadId(); qint64 fact=write(send); emit serverToClientFactByte(fact,handle); }}void tcpClient::getMSg(){ QString t; QDataStream in(this); in.setVersion(QDataStream::Qt_5_3); in>>blocksize>>t; clientToServerBlocks.append(t); qDebug()<<"客户--服务,触发!"<<blocksize; emit sendForReadMsg(handleback,clientToServerBlocks);}qint64 tcpClient::writeByte(QByteArray Blocks){ QByteArray send; QString t=Blocks; QDataStream out(&send,QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_3); out<<(quint64)(Blocks.size())<<t; qDebug()<<"客户线程:"<<QThread::currentThreadId(); qint64 fact=write(send); return fact;}#ifndef TCPCLIENT_H#define TCPCLIENT_H#include<QtNetwork/QTcpSocket>#include<QByteArray>class tcpClient : public QTcpSocket{ Q_OBJECTpublic: explicit tcpClient(qintptr handle,QObject *parent = 0); ~tcpClient(); void writeByte(QByteArray Blocks);//作为客户机的时候用这个函数,作为服务端的socket的时候,这个不用的。signals: void serverToClientFactByte(qint64 factByte,qintptr handle);//向server发送实际写入的字节 void IWantToClose(qintptr handle);//向server发送我被关闭的信号 void sendForReadMsg(qintptr,QByteArray);//向server发送读取信息成功的信号public slots: void serverToClientSlots(qintptr handle,const QByteArray &Blocks);//接受server写信号 void clientDisconnect();//这个不需要管。封装好的 void getMSg();//接受到了信息了private: qintptr handleback; quint64 blocksize; QByteArray clientToServerBlocks;};#endif // TCPCLIENT_H#include "tcpsever.h"#include"mydebug.h"TCPSever::TCPSever(QObject *parent) : QTcpServer(parent){ qRegisterMetaType<qintptr>("qintptr");}void TCPSever::incomingConnection(qintptr handle){ QThread *newClientThread=new QThread;//开辟线程 tcpClient *newClientsocket=new tcpClient(handle);//创建一个socket newClientsocket->setSocketDescriptor(handle);//设置套接字 strClients temp;//创建一个临时的对象、 newClientsocket->moveToThread(newClientThread);//把这个socket移动到线程中 connect(this,SIGNAL(serverWriteToClientSignal(qintptr,QByteArray)),newClientsocket,SLOT(serverToClientSlots(qintptr,QByteArray))); connect(newClientsocket,SIGNAL(serverToClientFactByte(qint64,qintptr)),this,SLOT(serverWriteToClientFactByte(qint64,qintptr))); connect(newClientsocket,SIGNAL(IWantToClose(qintptr)),this,SLOT(clientUserClosed(qintptr))); connect(newClientsocket,SIGNAL(sendForReadMsg(qintptr,QByteArray)),this,SLOT(clientToserverByte(qintptr,QByteArray))); temp.clientsSocket=newClientsocket;//保存结构体 temp.clientsSocketThread=newClientThread; mutex.lock(); Clients.insert(handle,temp);//插入到Qhash中。以后可以根据套接字得到那个结构体,结构体里面存的都是地址。可以用delete删掉 mutex.unlock(); ClientShow newClientMsg;//定义一个结构体,这个结构体是专门发送为GUI线程显示的。 quint16 po; po=newClientsocket->peerPort(); newClientMsg.ClientPort=QString::number(po); newClientMsg.ClientName=newClientsocket->peerName(); newClientMsg.ClientIP=newClientsocket->peerAddress().toString(); newClientMsg.handle=handle; emit sendSpecificHandle(newClientMsg);//告诉GUI来客人啦! newClientThread->start();#ifdef MYDEBUG qDebug()<<"新的连接!!";#endif}void TCPSever::clearSpecificSocket(qintptr handle){ //tcpClient *deleteClient=Clients.value(handle); strClients ClientDelete=Clients.value(handle); ClientDelete.clientsSocket->disconnectFromHost(); /* connect(this,SIGNAL(serverWriteToClientSignal(qintptr,QByteArray)),newClientsocket,SLOT(serverToClientSlots(qintptr,QByteArray))); connect(newClientsocket,SIGNAL(serverToClientFactByte(qint64,qintptr)),this,SLOT(serverWriteToClientFactByte(qint64,qintptr))); connect(newClientsocket,SIGNAL(IWantToClose(qintptr)),this,SLOT(clientUserClosed(qintptr))); */ disconnect(this,SIGNAL(serverWriteToClientSignal(qintptr,QByteArray)),ClientDelete.clientsSocket,SLOT(serverToClientSlots(qintptr,QByteArray))); disconnect(ClientDelete.clientsSocket,SIGNAL(serverToClientFactByte(qint64,qintptr)),this,SLOT(serverWriteToClientFactByte(qint64,qintptr))); disconnect(ClientDelete.clientsSocket,SIGNAL(IWantToClose(qintptr)),this,SLOT(clientUserClosed(qintptr))); disconnect(ClientDelete.clientsSocket,SIGNAL(sendForReadMsg(qintptr,QByteArray)),this,SLOT(clientToserverByte(qintptr,QByteArray))); delete ClientDelete.clientsSocket; ClientDelete.clientsSocketThread->quit(); ClientDelete.clientsSocketThread->wait(); delete ClientDelete.clientsSocketThread; mutex.lock(); Clients.remove(handle); mutex.unlock();}void TCPSever::serverWriteToClient(qintptr handle, const QByteArray &Blocks){ qDebug()<<"serverWriteToClient中的Blocks"<<Blocks; emit serverWriteToClientSignal(handle,Blocks);}void TCPSever::serverWriteToClientFactByte(qint64 factByte, qintptr handle){ emit writeFinshReturnToGUIFactByte(factByte,handle);}void TCPSever::clientUserClosed(qintptr handle){ clearSpecificSocket(handle); emit clientUserCLosedToGUI(handle); qDebug()<<"clientUserClosed";}void TCPSever::clientToserverByte(qintptr handle, QByteArray Blocks){ emit serverReadSucceeToGUI(handle,Blocks);}#ifndef TCPSEVER_H#define TCPSEVER_H#include<QtNetwork/QTcpServer>#include<QThread>#include<QtNetwork/QTcpSocket>#include<QHash>#include"tcpclient.h"#include<QByteArray>#include<QMutex>#include<QMutexLocker>struct strClients{ tcpClient *clientsSocket; QThread *clientsSocketThread;};class TCPSever : public QTcpServer{ Q_OBJECTpublic: explicit TCPSever(QObject *parent = 0); struct ClientShow { QString ClientName; QString ClientIP; QString ClientPort; qintptr handle; }; void incomingConnection(qintptr handle); void serverWriteToClient(qintptr handle, const QByteArray &Blocks);//由GUI线程调用,向指定的客户机发送指定的内容! void clearSpecificSocket(qintptr handle);//清除特定的客户机signals: //下面四个是给GUI发送信号的 void sendSpecificHandle(TCPSever::ClientShow sendClientMsg);//告诉GUI来客人啦! void serverReadSucceeToGUI(qintptr handle,QByteArray Blocks);//告诉GUI,客户机来信息了。 void writeFinshReturnToGUIFactByte(qint64,qintptr);//向GUI线程返回实际写的字节数 void clientUserCLosedToGUI(qintptr);//由clientUserClosed调用。给GUI的 //这个是给tcpclient发送信号的。 void serverWriteToClientSignal(qintptr handle,const QByteArray &Blocks);//向tcpclient对象发送信号,写指定的内容public slots: void serverWriteToClientFactByte(qint64 factByte,qintptr handle);//客户机给tcpserver发送的信号,底层封装好了,不用管 void clientUserClosed(qintptr handle);//接受客户机来的信号,并且发送信号给GUI,客人走了 void clientToserverByte(qintptr handle,QByteArray Blocks);//接受客户机发来的写信号。private: QMutex mutex;//互斥 QHash<qintptr,strClients> Clients; //管理客户机。};#endif // TCPSEVER_H//以下是验证代码...#include "tcpseverui.h"#include "ui_tcpseverui.h"#include"mydebug.h"#include<QList>TcpSeverUi::TcpSeverUi(QWidget *parent) : QWidget(parent), ui(new Ui::TcpSeverUi){ ui->setupUi(this); ui->disConnectionPushButton->setEnabled(false); ui->label->setText("未监听"); // ui->ClientTableWidget->setRowCount(30); ui->ClientTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->ClientTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); ui->ClientTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); servers=new TCPSever; // connect(servers,SIGNAL(sendSpecificHandle(TCPSever::ClientShow)),this,SLOT(getSpecifichandle(TCPSever::ClientShow))); connect(servers,SIGNAL(sendSpecificHandle(TCPSever::ClientShow)),this,SLOT(getSpecifichandle(TCPSever::ClientShow))); connect(servers,SIGNAL(writeFinshReturnToGUIFactByte(qint64,qintptr)),this,SLOT(toClientFactByte(qint64,qintptr))); connect(servers,SIGNAL(clientUserCLosedToGUI(qintptr)),this,SLOT(updateClientMsg(qintptr))); connect(servers,SIGNAL(serverReadSucceeToGUI(qintptr,QByteArray)),this,SLOT(readOKslot(qintptr,QByteArray))); qDebug()<<"GUI线程:"<<QThread::currentThreadId();}TcpSeverUi::~TcpSeverUi(){ delete ui;}void TcpSeverUi::on_connectionPushButton_clicked(){ int port=ui->portLineEdit->text().toInt(); if(servers->listen(QHostAddress::Any,port)==true) { ui->disConnectionPushButton->setEnabled(true); ui->connectionPushButton->setEnabled(false); ui->label->setText("正在监听"); } else { ui->label->setText("打开端口失败!"); }}void TcpSeverUi::on_disConnectionPushButton_clicked(){ servers->close(); ui->connectionPushButton->setEnabled(true); ui->disConnectionPushButton->setEnabled(false); ui->label->setText("未监听");}void TcpSeverUi::getSpecifichandle(TCPSever::ClientShow getClientMsg){#ifdef MYDEBUG qDebug()<<"IP="<<getClientMsg.ClientIP <<"端口:"<<getClientMsg.ClientPort <<"名字"<<getClientMsg.ClientName <<"套接字"<<getClientMsg.handle;#endif QMutexLocker locker(&mutex); GUIClientShow.insert(getClientMsg.handle,getClientMsg); //更新到UI界面 QTableWidgetItem *appenIP,*appenPort,*appendHandle; appenIP=new QTableWidgetItem(getClientMsg.ClientIP); appenPort=new QTableWidgetItem(getClientMsg.ClientPort); int row=ui->ClientTableWidget->rowCount(); ui->ClientTableWidget->insertRow(row); ui->ClientTableWidget->setItem(row,0,appenIP); ui->ClientTableWidget->setItem(row,1,appenPort); //QString handleShow; //handleShow=QString::number(getClientMsg.handle); appendHandle=new QTableWidgetItem(QString::number(getClientMsg.handle)); ui->ClientTableWidget->setItem(row,2,appendHandle); QString k=QString("hello %1,%2").arg(getClientMsg.ClientIP).arg(getClientMsg.ClientPort); qDebug()<<"发送的内容是"<<k<<"全部大小是"<<k.size(); QByteArray block(k.toStdString().c_str()); servers->serverWriteToClient(getClientMsg.handle,block);}TCPSever::ClientShow TcpSeverUi::readGUIClientMsg(qintptr handle){ QMutexLocker locker(&mutex); TCPSever::ClientShow temp; temp.ClientIP=GUIClientShow.value(handle).ClientIP; temp.ClientName=GUIClientShow.value(handle).ClientName; temp.ClientPort=GUIClientShow.value(handle).ClientPort; temp.handle=handle; return temp;}void TcpSeverUi::toClientFactByte(qint64 factByte, qintptr handle){#ifdef MYDEBUG qDebug()<<"实际写入的字节是"<<factByte<<",套接字为:"<<handle;#endif}void TcpSeverUi::on_deleteClientPushButton_clicked(){ int currentrow=ui->ClientTableWidget->currentRow(); QTableWidgetItem *handleItem=new QTableWidgetItem; handleItem=ui->ClientTableWidget->item(currentrow,2);//获取套接字的项 QString handleStr=handleItem->text(); qintptr handle=handleStr.toInt(); servers->clearSpecificSocket(handle); ui->ClientTableWidget->takeItem(currentrow,0); ui->ClientTableWidget->takeItem(currentrow,1); ui->ClientTableWidget->takeItem(currentrow,2);}void TcpSeverUi::updateClientMsg(qintptr handle){ QString t=QString::number(handle); QList<QTableWidgetItem *> find=ui->ClientTableWidget->findItems(t,Qt::MatchFixedString); QList<int> row; for(int i=0;i<find.size();i++) { row.append(ui->ClientTableWidget->row(find.at(i))); } for(int i=0;i<row.size();i++) { ui->ClientTableWidget->takeItem(row.at(i),0); ui->ClientTableWidget->takeItem(row.at(i),1); ui->ClientTableWidget->takeItem(row.at(i),2); }}void TcpSeverUi::readOKslot(qintptr handle, QByteArray Blocks){ qDebug()<<"收到的消息是"<<Blocks;}#ifndef TCPSEVERUI_H#define TCPSEVERUI_H#include <QWidget>#include<tcpsever.h>#include<QHash>#include<QMutexLocker>#include<QMutex>namespace Ui {class TcpSeverUi;}class TcpSeverUi : public QWidget{ Q_OBJECTpublic: explicit TcpSeverUi(QWidget *parent = 0); ~TcpSeverUi(); TCPSever::ClientShow readGUIClientMsg(qintptr handle);signals: //void sendClearHandle(qintptr handle);private slots: void on_connectionPushButton_clicked(); void getSpecifichandle(TCPSever::ClientShow getClientMsg); void toClientFactByte(qint64 factByte,qintptr handle); void on_disConnectionPushButton_clicked(); void updateClientMsg(qintptr handle); void on_deleteClientPushButton_clicked(); void readOKslot(qintptr handle,QByteArray Blocks);private: Ui::TcpSeverUi *ui; TCPSever *servers; QMutex mutex; QHash<qintptr,TCPSever::ClientShow> GUIClientShow;};#endif // TCPSEVERUI_H
0 0
- 自己写的 基于多线程和TCPserver类、TCPsocket的类
- C#的TcpClient和TCPSocket简单通信
- Qt的TCPsocket通信
- muduo库的TcpServer和TcpConnection用法
- Python的SocketServer中的类ThreadingTCPServer/TCPServer/ForkingTCPServer区别
- 自己写的socket 多线程 通讯
- 自己写的异步多线程队列
- 自己写的写日志类
- TCPServer 的一般参数
- Qt的tcpserver demo
- TCPServer 的一般参数
- Qt的tcpserver demo
- 自己写的Array类
- 自己写的 string 类
- 自己写的SqlHelper类
- 自己写的分页类
- 自己写的String类
- 自己写的CArray类
- 《c++ primer》第二章学习笔记
- POJ 2828 Buy Tickets
- 小白马卫士项目总结之手机防盗
- 析构函数、多态
- 递归数据是怎样制作出分组报表
- 自己写的 基于多线程和TCPserver类、TCPsocket的类
- 帮你理解特征向量的几何意义?
- HDOJ 5135(Little Zu Chongzhi's Triangles)
- WPF Expander-Template(default)
- 如何写一个正经的Android音乐播放器 一
- 我的第一篇博客
- CString to char*
- UILabel 学习笔记之设置圆角
- 填报监听类中获得报表名称