TcpSocket类
创建了QTcpSokcet类的实例后,可以用conncetToHost()与服务器进行连接:
QHostAddress *serverIP = new QHostAddress();
QString ip = serverIPLineEdit->text();
serverIP->setAddress(ip);
int port = 8010;
tcpSocket->connectToHost(*serverIP, port);
如果成功,将返回connected()信号,错误则返回error(QAbstrackSocket::SocketError socketError)信号
连接成功后可发送或接收数据:
发送:qunit64 write(const QByteArray &byteArray),发挥实际发送字节数,出错返回-1
接收:readyRead()信号被发送,在槽函数中编写处理数据代码,为避免错误解析数据,可用bytesAvailable()返回缓存中接收到的字节数。
断开:
disconnectFromHost()
TcpServer类
实现一个TCP服务器以监听网络上的连接请求。
listen(const QHostAddress& address, quint16 port); 如:listen(QHostAddress::Any, 8010);
收到连接请求时,incomingConnection(int)会被调用,可创建一个QTcpSocket对象来建立一个TCP连接。
其他
可用QTextStream和QDataStream接收或发送数据,前者以文本方式,后者以二进制方式
在.pro中添加:
QT += network12
服务器端
tcpclientsocket.h
#ifndef TCPCLIENTSOCKET_H#define TCPCLIENTSOCKET_H#include <QTcpSocket>#include <QObject>//用于与客户端通信class TcpClientSocket : public QTcpSocket { Q_OBJECTpublic: TcpClientSocket(QObject *parent=0); signals: void updateClients(QString,int); void disconnected(int);protected slots: void dataReceived(); void slotDisconnected(); };#endif // TCPCLIENTSOCKET_H123456789101112131415161718192021
tcpclientsoket.cpp
#include "tcpclientsocket.h"TcpClientSocket::TcpClientSocket(QObject *parent) { 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()); }1234567891011121314151617181920212223242526
tcpserver.h
#ifndef SERVER_H#define SERVER_H#include <QTcpServer>#include <QObject>#include "tcpclientsocket.h"//TCP服务器,监听指定端口的TCP连接class Server : public QTcpServer { Q_OBJECTpublic: 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_H12345678910111213141516171819202122232425
tcpserver.cpp
#include "tcpserver.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; } } }//将断开连接的TcpSocket对象删除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; }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
dialog.h
#ifndef TCPSERVER_H#define TCPSERVER_H#include <QDialog>#include <QListWidget>#include <QLabel>#include <QLineEdit>#include <QPushButton>#include <QGridLayout>#include "tcpserver.h"class TcpServer : public QDialog{ Q_OBJECTpublic: 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_H123456789101112131415161718192021222324252627282930313233
dialog.cpp
#include "dialog.h"TcpServer::TcpServer(QWidget *parent,Qt::WindowFlags f) : QDialog(parent,f) { setWindowTitle(tr("TCP Server")); ContentListWidget = new QListWidget; PortLabel = new QLabel(tr("端口:")); PortLineEdit = new QLineEdit; CreateBtn = new QPushButton(tr("创建聊天室")); 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)); }1234567891011121314151617181920212223242526272829303132333435363738394041424344
main.cpp
#include "mainwindow.h"#include "dialog.h"#include <QApplication>int main(int argc, char *argv[]) { QApplication a(argc, argv); TcpServer w; w.show(); return a.exec(); }123456789101112
客户端
tcpclient.h
#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_OBJECTpublic: 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_H12345678910111213141516171819202122232425262728293031323334353637383940414243444546
tcpclient.cpp
#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; serverIPLabel = new QLabel(tr("服务器地址:")); serverIPLineEdit = new QLineEdit; portLabel = new QLabel(tr("端口:")); portLineEdit = new QLineEdit; 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 = 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("进入聊天室")); }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())); } }123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
main.cpp
#include "tcpclient.h"#include <QApplication>int main(int argc, char *argv[]) { QApplication a(argc, argv); TcpClient w; w.show(); return a.exec(); }123456789101112