C:\Users\Minwei\Projects\Qt\TcpServer\tcpserverwindow.h:
xxxxxxxxxx
501
2
3
4
5
6
7
8
9
10QT_BEGIN_NAMESPACE
11namespace Ui { class TcpServerWindow; }
12QT_END_NAMESPACE
13
14class TcpServerWindow : public QMainWindow
15{
16 Q_OBJECT
17
18public:
19 TcpServerWindow(QWidget *parent = nullptr);
20 ~TcpServerWindow();
21
22private slots:
23 void on_m_actListen_triggered();
24 void on_m_actClose_triggered();
25 void on_m_actClear_triggered();
26
27 void on_m_btnSend_clicked();
28
29 void on_m_server_newConnection();
30
31 void on_m_socket_readyRead();
32 void on_m_socket_disconnected();
33
34 void on_m_socket_stateChanged(
35 QAbstractSocket::SocketState socketState);
36 void on_m_socket_error(
37 QAbstractSocket::SocketError socketError);
38
39private:
40 void broadcast(QByteArray const& data);
41
42 Ui::TcpServerWindow *ui;
43 QLabel* m_labListenState;
44 QLabel* m_labSocketState;
45 QLabel* m_labSocketError;
46 QTcpServer* m_server;
47 QVector<QTcpSocket*> m_sockets;
48};
49
50// TCPSERVERWINDOW_H
C:\Users\Minwei\Projects\Qt\TcpServer\tcpserverwindow.cpp:
x
1
2
3
4
5
6
7TcpServerWindow::TcpServerWindow(QWidget *parent)
8 : QMainWindow(parent)
9 , ui(new Ui::TcpServerWindow)
10 , m_labListenState(new QLabel("监听状态:关闭"))
11 , m_labSocketState(new QLabel(" 套接字状态:"))
12 , m_labSocketError(new QLabel(" 套接字错误:"))
13 , m_server(new QTcpServer(this))
14{
15 ui->setupUi(this);
16
17 for (QHostAddress address : QHostInfo::fromName(
18 QHostInfo::localHostName()).addresses())
19 if(address.protocol() == QAbstractSocket::IPv4Protocol)
20 ui->m_comboLocalAddr->addItem(address.toString());
21
22 m_labListenState->setMinimumWidth(196);
23 ui->m_statusBar->addWidget(m_labListenState);
24 m_labSocketState->setMinimumWidth(197);
25 ui->m_statusBar->addWidget(m_labSocketState);
26 m_labSocketError->setMinimumWidth(197);
27 ui->m_statusBar->addWidget(m_labSocketError);
28
29 connect(m_server, SIGNAL(newConnection()),
30 this, SLOT(on_m_server_newConnection()));
31}
32
33TcpServerWindow::~TcpServerWindow()
34{
35 delete ui;
36}
37
38void TcpServerWindow::on_m_actListen_triggered()
39{
40 QHostAddress address(ui->m_comboLocalAddr->currentText());
41 quint16 port = ui->m_editLocalPort->text().toUShort();
42
43 if (m_server->listen(address, port))
44 {
45 ui->m_editOutput->appendPlainText(QString("监听%1:%2成功").
46 arg(address.toString()).arg(port));
47 m_labListenState->setText(QString("监听状态:%1:%2").
48 arg(address.toString()).arg(port));
49 }
50 else
51 ui->m_editOutput->appendPlainText(QString("监听%1:%2失败").
52 arg(address.toString()).arg(port));
53}
54
55void TcpServerWindow::on_m_actClose_triggered()
56{
57 m_server->close();
58
59 ui->m_editOutput->appendPlainText("关闭监听");
60 m_labListenState->setText("监听状态:关闭");
61}
62
63void TcpServerWindow::on_m_actClear_triggered()
64{
65 ui->m_editOutput->clear();
66}
67
68void TcpServerWindow::on_m_btnSend_clicked()
69{
70 broadcast((ui->m_editSend->text() + "\n").toUtf8());
71}
72
73void TcpServerWindow::on_m_server_newConnection()
74{
75 QTcpSocket* socket = m_server->nextPendingConnection();
76
77 connect(socket, SIGNAL(readyRead()),
78 this, SLOT(on_m_socket_readyRead()));
79 connect(socket, SIGNAL(disconnected()),
80 this, SLOT(on_m_socket_disconnected()));
81
82 connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
83 this, SLOT(on_m_socket_stateChanged(QAbstractSocket::SocketState)));
84 connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
85 this, SLOT(on_m_socket_error(QAbstractSocket::SocketError)));
86
87 ui->m_editOutput->appendPlainText(QString("接受%1:%2连接").
88 arg(socket->peerAddress().toString()).arg(socket->peerPort()));
89
90 m_sockets.push_back(socket);
91 ui->m_btnSend->setEnabled(!m_sockets.isEmpty());
92}
93
94void TcpServerWindow::on_m_socket_readyRead()
95{
96 QTcpSocket* socket = (QTcpSocket*)sender();
97
98 while (socket->canReadLine())
99 {
100 QByteArray data = socket->readLine();
101
102 ui->m_editOutput->appendPlainText(QString("从%1:%2接收%3字节:%4").
103 arg(socket->peerAddress().toString()).arg(socket->peerPort()).
104 arg(data.size()).arg(QString(data).trimmed()));
105 }
106}
107
108void TcpServerWindow::on_m_socket_disconnected()
109{
110 QTcpSocket* socket = (QTcpSocket*)sender();
111
112 m_sockets.removeOne(socket);
113 ui->m_btnSend->setEnabled(!m_sockets.isEmpty());
114
115 ui->m_editOutput->appendPlainText(QString("断开%1:%2连接").
116 arg(socket->peerAddress().toString()).arg(socket->peerPort()));
117
118 socket->deleteLater();
119}
120
121void TcpServerWindow::on_m_socket_stateChanged(
122 QAbstractSocket::SocketState socketState)
123{
124 m_labSocketState->setText(QString(" 套接字状态:%1").arg(
125 QMetaEnum::fromType<QAbstractSocket::SocketState>().
126 valueToKey(socketState)));
127}
128
129void TcpServerWindow::on_m_socket_error(
130 QAbstractSocket::SocketError socketError)
131{
132 m_labSocketError->setText(QString(" 套接字错误:%1").arg(
133 QMetaEnum::fromType<QAbstractSocket::SocketError>().
134 valueToKey(socketError)));
135}
136
137void TcpServerWindow::broadcast(QByteArray const& data)
138{
139 for (QTcpSocket* socket : m_sockets)
140 {
141 qint64 nbytes = socket->write(data);
142
143 if (nbytes == -1)
144 ui->m_editOutput->appendPlainText("发送失败");
145 else
146 ui->m_editOutput->appendPlainText(QString("向%1:%2发送%3字节:%4").
147 arg(socket->peerAddress().toString()).arg(socket->peerPort()).
148 arg(nbytes).arg(QString(data).trimmed()));
149 }
150}
运行效果如图所示:
C:\Users\Minwei\Projects\Qt\TcpServer\tcpserverwindow.cpp:
x
1
2
3
4
5
6
7TcpServerWindow::TcpServerWindow(QWidget *parent)
8 : QMainWindow(parent)
9 , ui(new Ui::TcpServerWindow)
10 , m_labListenState(new QLabel("监听状态:关闭"))
11 , m_labSocketState(new QLabel(" 套接字状态:"))
12 , m_labSocketError(new QLabel(" 套接字错误:"))
13 , m_server(new QTcpServer(this))
14{
15 ui->setupUi(this);
16
17 for (QHostAddress address : QHostInfo::fromName(
18 QHostInfo::localHostName()).addresses())
19 if(address.protocol() == QAbstractSocket::IPv4Protocol)
20 ui->m_comboLocalAddr->addItem(address.toString());
21
22 m_labListenState->setMinimumWidth(196);
23 ui->m_statusBar->addWidget(m_labListenState);
24 m_labSocketState->setMinimumWidth(197);
25 ui->m_statusBar->addWidget(m_labSocketState);
26 m_labSocketError->setMinimumWidth(197);
27 ui->m_statusBar->addWidget(m_labSocketError);
28
29 connect(m_server, SIGNAL(newConnection()),
30 this, SLOT(on_m_server_newConnection()));
31}
32
33TcpServerWindow::~TcpServerWindow()
34{
35 delete ui;
36}
37
38void TcpServerWindow::on_m_actListen_triggered()
39{
40 QHostAddress address(ui->m_comboLocalAddr->currentText());
41 quint16 port = ui->m_editLocalPort->text().toUShort();
42
43 if (m_server->listen(address, port))
44 {
45 ui->m_editOutput->appendPlainText(QString("监听%1:%2成功").
46 arg(address.toString()).arg(port));
47 m_labListenState->setText(QString("监听状态:%1:%2").
48 arg(address.toString()).arg(port));
49 }
50 else
51 ui->m_editOutput->appendPlainText(QString("监听%1:%2失败").
52 arg(address.toString()).arg(port));
53}
54
55void TcpServerWindow::on_m_actClose_triggered()
56{
57 m_server->close();
58
59 ui->m_editOutput->appendPlainText("关闭监听");
60 m_labListenState->setText("监听状态:关闭");
61}
62
63void TcpServerWindow::on_m_actClear_triggered()
64{
65 ui->m_editOutput->clear();
66}
67
68void TcpServerWindow::on_m_btnSend_clicked()
69{
70 broadcast((ui->m_editSend->text() + "\n").toUtf8());
71}
72
73void TcpServerWindow::on_m_server_newConnection()
74{
75 QTcpSocket* socket = m_server->nextPendingConnection();
76
77 connect(socket, SIGNAL(readyRead()),
78 this, SLOT(on_m_socket_readyRead()));
79 connect(socket, SIGNAL(disconnected()),
80 this, SLOT(on_m_socket_disconnected()));
81
82 connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
83 this, SLOT(on_m_socket_stateChanged(QAbstractSocket::SocketState)));
84 connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
85 this, SLOT(on_m_socket_error(QAbstractSocket::SocketError)));
86
87 ui->m_editOutput->appendPlainText(QString("接受%1:%2连接").
88 arg(socket->peerAddress().toString()).arg(socket->peerPort()));
89
90 m_sockets.push_back(socket);
91 ui->m_btnSend->setEnabled(!m_sockets.isEmpty());
92}
93
94void TcpServerWindow::on_m_socket_readyRead()
95{
96 QTcpSocket* socket = (QTcpSocket*)sender();
97
98 while (socket->canReadLine())
99 {
100 QByteArray data = socket->readLine();
101
102 ui->m_editOutput->appendPlainText(QString("从%1:%2接收%3字节:%4").
103 arg(socket->peerAddress().toString()).arg(socket->peerPort()).
104 arg(data.size()).arg(QString(data).trimmed()));
105
106 broadcast(data);
107 }
108}
109
110void TcpServerWindow::on_m_socket_disconnected()
111{
112 QTcpSocket* socket = (QTcpSocket*)sender();
113
114 m_sockets.removeOne(socket);
115 ui->m_btnSend->setEnabled(!m_sockets.isEmpty());
116
117 ui->m_editOutput->appendPlainText(QString("断开%1:%2连接").
118 arg(socket->peerAddress().toString()).arg(socket->peerPort()));
119
120 socket->deleteLater();
121}
122
123void TcpServerWindow::on_m_socket_stateChanged(
124 QAbstractSocket::SocketState socketState)
125{
126 m_labSocketState->setText(QString(" 套接字状态:%1").arg(
127 QMetaEnum::fromType<QAbstractSocket::SocketState>().
128 valueToKey(socketState)));
129}
130
131void TcpServerWindow::on_m_socket_error(
132 QAbstractSocket::SocketError socketError)
133{
134 m_labSocketError->setText(QString(" 套接字错误:%1").arg(
135 QMetaEnum::fromType<QAbstractSocket::SocketError>().
136 valueToKey(socketError)));
137}
138
139void TcpServerWindow::broadcast(QByteArray const& data)
140{
141 for (QTcpSocket* socket : m_sockets)
142 {
143 qint64 nbytes = socket->write(data);
144
145 if (nbytes == -1)
146 ui->m_editOutput->appendPlainText("发送失败");
147 else
148 ui->m_editOutput->appendPlainText(QString("向%1:%2发送%3字节:%4").
149 arg(socket->peerAddress().toString()).arg(socket->peerPort()).
150 arg(nbytes).arg(QString(data).trimmed()));
151 }
152}
运行效果如图所示: