日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt_套接字

發(fā)布時間:2023/12/29 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt_套接字 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在網(wǎng)上找了好多有關(guān)套接字的博客,看了一些代碼,復(fù)制下來跑的時候總是不出來,然后在QDocument上找到了一個例子程序,就復(fù)制下來了??创a的時候里面用到了好的類,好像是用來保存一個網(wǎng)絡(luò)設(shè)置的,沒看懂,然后就吧這部分給刪了 = =。
運行的結(jié)果

源代碼

server.h

#ifndef SERVER_H #define SERVER_H#include <QDialog>class QLabel; class QPushButton; class QTcpServer;class Server : public QDialog {Q_OBJECTpublic:Server(QWidget *parent = 0);private slots:void sendFortune();private:QLabel *statusLabel;QPushButton *quitButton;QTcpServer *tcpServer;QStringList fortunes; };#endif

server.cpp

#include <QtWidgets> #include <QtNetwork>#include <stdlib.h>#include "server.h"Server::Server(QWidget *parent) : QDialog(parent), tcpServer(0) {statusLabel = new QLabel;quitButton = new QPushButton(tr("Quit"));quitButton->setAutoDefault(false);tcpServer = new QTcpServer(this);if (!tcpServer->listen()) {QMessageBox::critical(this, tr("Fortune Server"),tr("Unable to start the server: %1.").arg(tcpServer->errorString()));close();return;}QString ipAddress;QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();// use the first non-localhost IPv4 addressfor (int i = 0; i < ipAddressesList.size(); ++i) {if (ipAddressesList.at(i) != QHostAddress::LocalHost &&ipAddressesList.at(i).toIPv4Address()) {ipAddress = ipAddressesList.at(i).toString();break;}}// if we did not find one, use IPv4 localhostif (ipAddress.isEmpty())ipAddress = QHostAddress(QHostAddress::LocalHost).toString();statusLabel->setText(tr("The server is running on\n\nIP: %1\nport: %2\n\n""Run the Fortune Client example now.").arg(ipAddress).arg(tcpServer->serverPort()));fortunes << tr("1")<< tr("2")<< tr("3")<< tr("4")<< tr("5")<< tr("You cannot kill time without injuring eternity.")<< tr("Computers are not intelligent. They only think they are.");connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFortune()));QHBoxLayout *buttonLayout = new QHBoxLayout;buttonLayout->addStretch(1);buttonLayout->addWidget(quitButton);buttonLayout->addStretch(1);QVBoxLayout *mainLayout = new QVBoxLayout;mainLayout->addWidget(statusLabel);mainLayout->addLayout(buttonLayout);setLayout(mainLayout);setWindowTitle(tr("Fortune Server"));}void Server::sendFortune() {QByteArray block;QDataStream out(&block, QIODevice::WriteOnly);out.setVersion(QDataStream::Qt_4_0);out << (quint16)0;out << fortunes.at(qrand() % fortunes.size());out.device()->seek(0);out << (quint16)(block.size() - sizeof(quint16));QTcpSocket *clientConnection = tcpServer->nextPendingConnection();connect(clientConnection, SIGNAL(disconnected()),clientConnection, SLOT(deleteLater()));clientConnection->write(block);clientConnection->disconnectFromHost(); }

main.cpp

#include <QApplication> #include <QtCore>#include <stdlib.h>#include "server.h"int main(int argc, char *argv[]) {QApplication app(argc, argv);Server server;server.show();qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));return app.exec(); }

client.h

#ifndef CLIENT_H #define CLIENT_H#include <QDialog> #include <QTcpSocket>class QComboBox; class QDialogButtonBox; class QLabel; class QLineEdit; class QPushButton; class QTcpSocket; class QNetworkSession;class Client : public QDialog {Q_OBJECTpublic:Client(QWidget *parent = 0);private slots:void requestNewFortune();void readFortune();void displayError(QAbstractSocket::SocketError socketError);private:QLabel *hostLabel;QLabel *portLabel;QComboBox *hostCombo;QLineEdit *portLineEdit;QLabel *statusLabel;QPushButton *getFortuneButton;QPushButton *quitButton;QDialogButtonBox *buttonBox;QTcpSocket *tcpSocket;QString currentFortune;quint16 blockSize;//QNetworkSession *networkSession; };#endif

client.cpp

#include <QtWidgets> #include <QtNetwork>#include "client.h"Client::Client(QWidget *parent) : QDialog(parent) {hostLabel = new QLabel(tr("&Server name:"));portLabel = new QLabel(tr("S&erver port:"));hostCombo = new QComboBox;hostCombo->setEditable(true);// find out name of this machineQString name = QHostInfo::localHostName();if (!name.isEmpty()) {hostCombo->addItem(name);QString domain = QHostInfo::localDomainName();if (!domain.isEmpty())hostCombo->addItem(name + QChar('.') + domain);}if (name != QString("localhost"))hostCombo->addItem(QString("localhost"));// find out IP addresses of this machineQList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();// add non-localhost addressesfor (int i = 0; i < ipAddressesList.size(); ++i) {if (!ipAddressesList.at(i).isLoopback())hostCombo->addItem(ipAddressesList.at(i).toString());}// add localhost addressesfor (int i = 0; i < ipAddressesList.size(); ++i) {if (ipAddressesList.at(i).isLoopback())hostCombo->addItem(ipAddressesList.at(i).toString());}portLineEdit = new QLineEdit;portLineEdit->setValidator(new QIntValidator(1, 65535, this));hostLabel->setBuddy(hostCombo);portLabel->setBuddy(portLineEdit);statusLabel = new QLabel(tr("This examples requires that you run the ""Fortune Server example as well."));getFortuneButton = new QPushButton(tr("Get Fortune"));getFortuneButton->setDefault(true);getFortuneButton->setEnabled(true);quitButton = new QPushButton(tr("Quit"));buttonBox = new QDialogButtonBox;buttonBox->addButton(getFortuneButton, QDialogButtonBox::ActionRole);buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);tcpSocket = new QTcpSocket(this);connect(getFortuneButton, SIGNAL(clicked()),this, SLOT(requestNewFortune()));connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readFortune()));connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(displayError(QAbstractSocket::SocketError)));QGridLayout *mainLayout = new QGridLayout;mainLayout->addWidget(hostLabel, 0, 0);mainLayout->addWidget(hostCombo, 0, 1);mainLayout->addWidget(portLabel, 1, 0);mainLayout->addWidget(portLineEdit, 1, 1);mainLayout->addWidget(statusLabel, 2, 0, 1, 2);mainLayout->addWidget(buttonBox, 3, 0, 1, 2);setLayout(mainLayout);setWindowTitle(tr("Fortune Client"));portLineEdit->setFocus(); }void Client::requestNewFortune() {getFortuneButton->setEnabled(false);blockSize = 0;tcpSocket->abort();tcpSocket->connectToHost(hostCombo->currentText(),portLineEdit->text().toInt()); }void Client::readFortune() {QDataStream in(tcpSocket);in.setVersion(QDataStream::Qt_4_0);if (blockSize == 0) {if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))return;in >> blockSize;}if (tcpSocket->bytesAvailable() < blockSize)return;QString nextFortune;in >> nextFortune;if (nextFortune == currentFortune) {QTimer::singleShot(0, this, SLOT(requestNewFortune()));return;}currentFortune = nextFortune;statusLabel->setText(currentFortune);getFortuneButton->setEnabled(true); }void Client::displayError(QAbstractSocket::SocketError socketError) {switch (socketError) {case QAbstractSocket::RemoteHostClosedError:break;case QAbstractSocket::HostNotFoundError:QMessageBox::information(this, tr("Fortune Client"),tr("The host was not found. Please check the ""host name and port settings."));break;case QAbstractSocket::ConnectionRefusedError:QMessageBox::information(this, tr("Fortune Client"),tr("The connection was refused by the peer. ""Make sure the fortune server is running, ""and check that the host name and port ""settings are correct."));break;default:QMessageBox::information(this, tr("Fortune Client"),tr("The following error occurred: %1.").arg(tcpSocket->errorString()));}getFortuneButton->setEnabled(true); }

main.cpp

#include <QApplication> #include "client.h"int main(int argc, char *argv[]) {QApplication app(argc, argv);Client client;client.show();return app.exec(); }

分析

直接從cpp文件開始看
server.cpp

server的構(gòu)造函數(shù)

Server::Server(QWidget *parent) : QDialog(parent), tcpServer(0) {//創(chuàng)建了一個label和按鈕對象statusLabel = new QLabel;quitButton = new QPushButton(tr("Quit"));quitButton->setAutoDefault(false);//新建一個tcpserver充當服務(wù)器tcpServer = new QTcpServer(this);//調(diào)用tcpserver的函數(shù)listen來監(jiān)聽是否有客戶端連接,listen的第一個參數(shù)是客戶端的ip地址,第二個參數(shù)是監(jiān)聽的端口號,若不填則為任意ip的值和一個隨機的端口號if (!tcpServer->listen()) {//如果沒有成功監(jiān)聽報錯并返回QMessageBox::critical(this, tr("Fortune Server"),tr("Unable to start the server: %1.").arg(tcpServer->errorString()));close();return;}//定義了一個ip地址的鏈表//QNetworkInterface的靜態(tài)方法allAddresses返回了一個ip地址的鏈表,里面包含了所有在這臺主機上的ip地址。QString ipAddress;QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();//使用第一個不是本機ip的地址(并不知道是什么意思= =)for (int i = 0; i < ipAddressesList.size(); ++i) {if (ipAddressesList.at(i) != QHostAddress::LocalHost &&ipAddressesList.at(i).toIPv4Address()) {ipAddress = ipAddressesList.at(i).toString();break;}}//如果沒有找到就用本地主機的ipv4地址if (ipAddress.isEmpty())ipAddress = QHostAddress(QHostAddress::LocalHost).toString();//顯示服務(wù)器的ip地址和端口號statusLabel->setText(tr("The server is running on\n\nIP: %1\nport: %2\n\n""Run the Fortune Client example now.").arg(ipAddress).arg(tcpServer->serverPort()));//將要隨機顯示的字符串放到字符串鏈表fortunes中fortunes << tr("1")<< tr("2")<< tr("3")<< tr("4")<< tr("5")<< tr("You cannot kill time without injuring eternity.")<< tr("Computers are not intelligent. They only think they are.");//將退出按鈕的點擊信號和關(guān)閉界面的槽關(guān)聯(lián)起來connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));//將新的連接信號和發(fā)送字符串的槽連接起來connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFortune()));//設(shè)置布局管理器QHBoxLayout *buttonLayout = new QHBoxLayout;buttonLayout->addStretch(1);buttonLayout->addWidget(quitButton);buttonLayout->addStretch(1);QVBoxLayout *mainLayout = new QVBoxLayout;mainLayout->addWidget(statusLabel);mainLayout->addLayout(buttonLayout);setLayout(mainLayout);setWindowTitle(tr("Fortune Server"));}

發(fā)送字符串的函數(shù)

void Server::sendFortune() {//定義了一個字節(jié)數(shù)組QByteArray block;//定義了一個數(shù)據(jù)流QDataStream out(&block, QIODevice::WriteOnly);out.setVersion(QDataStream::Qt_4_0);out << (quint16)0;//將字符鏈表里隨機一個字符串放入到流里面out << fortunes.at(qrand() % fortunes.size());out.device()->seek(0);out << (quint16)(block.size() - sizeof(quint16));//定義一個套接字用來發(fā)送這個流//QTcpServer的nextPendingConnection函數(shù)就就是用來返回正在與服務(wù)器相連的套接字相對應(yīng)的一個套接字。QTcpSocket *clientConnection = tcpServer->nextPendingConnection();connect(clientConnection, SIGNAL(disconnected()),clientConnection, SLOT(deleteLater()));//將剛才的流通過套接字的write函數(shù)發(fā)送到客戶端clientConnection->write(block);clientConnection->disconnectFromHost(); }

client.cpp

Client::Client(QWidget *parent) : QDialog(parent) {//初始化兩個label和一個下拉框hostLabel = new QLabel(tr("&Server name:"));portLabel = new QLabel(tr("S&erver port:"));hostCombo = new QComboBox;hostCombo->setEditable(true);// 找到本機的名稱QString name = QHostInfo::localHostName();if (!name.isEmpty()) {hostCombo->addItem(name);QString domain = QHostInfo::localDomainName();if (!domain.isEmpty())hostCombo->addItem(name + QChar('.') + domain);}if (name != QString("localhost"))hostCombo->addItem(QString("localhost"));// 找出本機的ip地址并添加,和服務(wù)器的類似QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();for (int i = 0; i < ipAddressesList.size(); ++i) {if (!ipAddressesList.at(i).isLoopback())hostCombo->addItem(ipAddressesList.at(i).toString());}for (int i = 0; i < ipAddressesList.size(); ++i) {if (ipAddressesList.at(i).isLoopback())hostCombo->addItem(ipAddressesList.at(i).toString());}portLineEdit = new QLineEdit;portLineEdit->setValidator(new QIntValidator(1, 65535, this));hostLabel->setBuddy(hostCombo);portLabel->setBuddy(portLineEdit);statusLabel = new QLabel(tr("This examples requires that you run the ""Fortune Server example as well."));getFortuneButton = new QPushButton(tr("Get Fortune"));getFortuneButton->setDefault(true);getFortuneButton->setEnabled(true);quitButton = new QPushButton(tr("Quit"));buttonBox = new QDialogButtonBox;buttonBox->addButton(getFortuneButton, QDialogButtonBox::ActionRole);buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);//初始化套接字,用于和主機通訊tcpSocket = new QTcpSocket(this);//將點擊按鈕和獲得字符串關(guān)聯(lián)起來connect(getFortuneButton, SIGNAL(clicked()),this, SLOT(requestNewFortune()));//將退出按鈕和關(guān)閉窗口關(guān)聯(lián)起來connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));//將套接字的獲取到新的數(shù)據(jù)流信號和讀取數(shù)據(jù)槽關(guān)聯(lián)起來connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readFortune()));//將套接字的錯誤與錯誤函數(shù)關(guān)聯(lián)起來connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(displayError(QAbstractSocket::SocketError)));//設(shè)置布局管理器QGridLayout *mainLayout = new QGridLayout;mainLayout->addWidget(hostLabel, 0, 0);mainLayout->addWidget(hostCombo, 0, 1);mainLayout->addWidget(portLabel, 1, 0);mainLayout->addWidget(portLineEdit, 1, 1);mainLayout->addWidget(statusLabel, 2, 0, 1, 2);mainLayout->addWidget(buttonBox, 3, 0, 1, 2);setLayout(mainLayout);setWindowTitle(tr("Fortune Client"));portLineEdit->setFocus(); }

requestnewfortune函數(shù)

void Client::requestNewFortune() {//初始化數(shù)據(jù)塊大小的值blockSize = 0;//終止當前的連接并重置套接字tcpSocket->abort();//連接到主機,如果找到主機名稱,套接字就會發(fā)出找到hostFound()信//號并開始連接,如果連接成功就會發(fā)出connected()信號并進入連接狀態(tài)tcpSocket->connectToHost(hostCombo->currentText(),portLineEdit->text().toInt()); }

讀取字符串函數(shù)

void Client::readFortune() {//qt中的套接字繼承了QIODevice,所以可以類似于讀取文件的方式來讀取內(nèi)容QDataStream in(tcpSocket);in.setVersion(QDataStream::Qt_4_0);//bytesAvailable()函數(shù)是返回套接字中數(shù)據(jù)流的大小if (blockSize == 0) {if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))return;in >> blockSize;}if (tcpSocket->bytesAvailable() < blockSize)return;//將套接字中的內(nèi)容寫入到字符串中QString nextFortune;in >> nextFortune;if (nextFortune == currentFortune) {QTimer::singleShot(0, this, SLOT(requestNewFortune()));return;}currentFortune = nextFortune;statusLabel->setText(currentFortune); }

總結(jié)

以上是生活随笔為你收集整理的Qt_套接字的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。