tcpserver.h
#define TCPSERVER_H
#include <QtGui>
#include <QtNetwork>
#include "server.h"
class TcpServer : public QWidget
{
Q_OBJECT
public:
TcpServer( QWidget *parent=0, Qt::WindowFlags f=0 );//构造函数
~TcpServer();
public:
QListWidget *ListWidgetContent;//项目的清单部件
QLabel* LabelPort;//标签
QLineEdit* LineEditPort;//行编辑
QPushButton* PushButtonCreate;//按钮
int port;//int类型,将来做端口
Server *server;//类
public ://公共槽
void slotCreateServer();
void updateServer(QString,int);
};
#endif
tcpserver.cpp
TcpServer::TcpServer( QWidget *parent, Qt::WindowFlags f ) : QWidget( parent, f )
{
QFont font("Times",12,QFont::Normal,FALSE);
setFont(font);
setWindowTitle(tr("TCP服务器"));
QVBoxLayout *vbMain = new QVBoxLayout( this );//布局
ListWidgetContent = new QListWidget( this);//项目的清单部件
vbMain->addWidget( ListWidgetContent ); //把项目的清单部件加入到布局
QHBoxLayout *hb = new QHBoxLayout( );//布局
LabelPort = new QLabel( this );//标签
LabelPort->setText(tr("端口:"));//标签文字
hb->addWidget( LabelPort );//把标签加入到布局
LineEditPort = new QLineEdit(this);//行编辑
hb->addWidget( LineEditPort );//把行编辑加入到布局
vbMain->addLayout(hb);//加入布局
PushButtonCreate = new QPushButton( this);//按钮
PushButtonCreate->setText( tr( "启动" ) );//设置按钮文字
vbMain->addWidget( PushButtonCreate );//把按按钮加入到布局
//点击按钮时的信号槽,调用函数slotCreateServer
connect(PushButtonCreate,SIGNAL(clicked()),this,SLOT(slotCreateServer()));
port = 8089;//端口
//设置行编辑上的文字,在很多时候你不希望你的端口让别人知道,所以你可以不用下面的语句
LineEditPort->setText(QString::number(port));
}
TcpServer::~TcpServer()
{
}
//上面按钮点击时所调用的函数
void TcpServer::slotCreateServer()
{
//实列化对象并传参类,this,当前的窗口句柄,port端口
server = new Server(this,port);
//触发信号,调用函数upbateserver传两个参数
connect(server,SIGNAL(updateServer(QString,int)),this,SLOT(updateServer(QString,int)));
//设置按钮关闭,也就是不可用
PushButtonCreate->setEnabled(false);
}
//上面触发信号时所调用的函数接收两个参数
void TcpServer::updateServer(QString msg,int length)
{
ListWidgetContent->addItem (msg.left(length) );
}
server.h
#ifndef SERVER_H
#define SERVER_H
#include <QtNetwork>
#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.cpp
#include <QtNetwork>
#include "server.h"
Server::Server(QObject *parent,int port): QTcpServer(parent){
listen(QHostAddress::Any,port);
}
void Server::incomingConnection(int socketDescriptor)
{
//实列化对象
TcpClientSocket *tcpClientSocket = new TcpClientSocket(this);
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;
}
tcpclientsocket.h
#ifndef TCPCLIENTSOCKET_H
#define TCPCLIENTSOCKET_H
#include <QtGui>
#include <QtNetwork>
class TcpClientSocket : public QTcpSocket
{
Q_OBJECT
public:
TcpClientSocket( QObject *parent=0);//构造函数
~TcpClientSocket();
signals://信号函数
void updateClients(QString,int);
void disconnected(int);
protected slots://保护槽函数
void dataReceived();
void slotDisconnected();
};
#endif
tcpclientsocket.cpp
#include "tcpserver.h"
TcpClientSocket::TcpClientSocket( QObject *parent)
{ //此函数因继承了QTcpSocket,把会有readyRead信号发出,disconnected是自义的一个信号
connect(this, SIGNAL(readyRead()),this, SLOT(dataReceived()));
connect(this, SIGNAL(disconnected()),this, SLOT(slotDisconnected()));
}
TcpClientSocket::~TcpClientSocket()
{
}
void TcpClientSocket::dataReceived()//上面信号槽调用函数
{
while (bytesAvailable()>0)
{
//定义一个数组
char buf[1024];
//取服务器接收到的数据的长度
int length=bytesAvailable();
//读取
read(buf, length);
//赋值给msg
QString msg=buf;
//发送信号
emit updateClients(msg,length);
}
}
void TcpClientSocket::slotDisconnected()
{
emit disconnected(this->socketDescriptor ());
}
main.cpp
#include "tcpserver.h"
#include <QApplication>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));
QFont font("Times",12,QFont::Normal,FALSE);
a.setFont(font);
TcpServer *tcpserver = new TcpServer();
tcpserver->show();
return a.exec();
}