Qt的UDP编程
来源:互联网 发布:js当窗口大小变化 编辑:程序博客网 时间:2024/06/05 22:52
实现的是用户登录既是服务器端也是客户端。
服务器端:创建UDP端口,绑定固定端口,用信号和槽机制来监听是否有数据来临,如果有,读取数据的消息类型,如果是新用户登录消息,读取新用户信息,在用户列表中添加用户信息,如果是聊天信息,读取信息,显示在聊天窗口中。如果是下线信息,就读取用户信息,用户列表中删除,流程如下:
客户端:登录时获取用户名、主机名和IP地址,并广播给局域网中的服务器,更新用户列表。当用聊天信息有发送时,将用户名、主机名和IP地址及聊天信息广播出去,流程如下:
程序代码如下:
widget.h
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>#include <QUdpSocket>namespace Ui {class Widget;}enum MessageType {Message, NewParticipant, ParticipantLeft, FileName, Refuse};class Widget : public QWidget{ Q_OBJECTpublic: explicit Widget(QWidget *parent = 0); ~Widget();protected: void newParticipant(QString userName, QString localHostName, QString ipAddress); void participantLeft(QString userNme, QString localHostName, QString time); void sendMessage(MessageType type, QString serverAddress = ""); QString getIP(); QString getUserName(); QString getMessage();private slots: void prcessPendingDatagrams(); void on_sendButton_clicked();private: Ui::Widget *ui; QUdpSocket *udpSocket; quint16 port;};#endif // WIDGET_H
widget.cpp
#include "widget.h"#include "ui_widget.h"#include <QHostInfo>#include <QMessageBox>#include <QScrollBar>#include <QDateTime>#include <QNetworkInterface>#include <QProcess>#include <QTableWidgetItem>Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget){ ui->setupUi(this); udpSocket = new QUdpSocket(this); port = 45454; udpSocket->bind(port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); connect(udpSocket,SIGNAL(readyRead()), this, SLOT(prcessPendingDatagrams())); sendMessage(NewParticipant);}Widget::~Widget(){ delete ui;}void Widget::sendMessage(MessageType type, QString serverAddress){ QByteArray data; QDataStream out(&data, QIODevice::WriteOnly); QString localHostName = QHostInfo::localHostName(); QString address = getIP(); out << type << getUserName() << localHostName; switch (type) { case Message: if (ui->messageTextEdit->toPlainText() == "") { QMessageBox::warning(0, QStringLiteral("警告"), QStringLiteral("发送内容不能为空"), QMessageBox::Ok); return; } out << address << getMessage(); ui->messageBrowser->verticalScrollBar()->setValue(ui->messageBrowser->verticalScrollBar()->maximum()); break; case NewParticipant: out << address; break; case ParticipantLeft: break; case FileName: break; case Refuse: break; } udpSocket->writeDatagram(data, data.length(), QHostAddress::Broadcast, port);}void Widget::prcessPendingDatagrams(){ while (udpSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size()); QDataStream in(&datagram, QIODevice::ReadOnly); int messageType; in >> messageType; QString userName, localHostName, ipAddress, message; QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); switch (messageType) { case Message: in >> userName >> localHostName >> ipAddress >> message; ui->messageBrowser->setTextColor(Qt::blue); ui->messageBrowser->setCurrentFont(QFont("Times New Roman", 12)); ui->messageBrowser->append("[" + localHostName + "]" + time); ui->messageBrowser->append(message); break; case NewParticipant: in >> userName >> localHostName >> ipAddress; newParticipant(userName, localHostName,ipAddress); break; case ParticipantLeft: in >> userName >> localHostName; participantLeft(userName, localHostName, time); break; case FileName: case Refuse: break; } }}void Widget::newParticipant(QString userName, QString localHostName, QString ipAddress){ bool isEmpty = ui->userTableWidget->findItems(localHostName, Qt::MatchExactly).isEmpty(); if (isEmpty) { QTableWidgetItem* user = new QTableWidgetItem(userName); QTableWidgetItem* host = new QTableWidgetItem(localHostName); QTableWidgetItem* ip = new QTableWidgetItem(ipAddress); ui->userTableWidget->insertRow(0); ui->userTableWidget->setItem(0, 0, user); ui->userTableWidget->setItem(0, 1, host); ui->userTableWidget->setItem(0, 2, ip); ui->messageBrowser->setTextColor(Qt::gray); ui->messageBrowser->setCurrentFont(QFont("Times New Roman", 10)); ui->messageBrowser->append(QStringLiteral("%1 在线!").arg(userName)); ui->userNumLabel->setText(QStringLiteral("在线人数:%1").arg(ui->userTableWidget->rowCount())); }}void Widget::participantLeft(QString userNme, QString localHostName, QString time){ int rowNum = ui->userTableWidget->findItems(localHostName, Qt::MatchExactly).first()->row(); ui->userTableWidget->removeRow(rowNum); ui->messageBrowser->setTextColor(Qt::gray); ui->messageBrowser->setCurrentFont(QFont("Times New Roman", 10)); ui->messageBrowser->append(QStringLiteral("%1 于 %2离开").arg(userNme).arg(time)); ui->userNumLabel->setText(QStringLiteral("在线人数:%1").arg(ui->userTableWidget->rowCount()));}QString Widget::getIP(){ QList<QHostAddress> list = QNetworkInterface::allAddresses(); foreach(QHostAddress address, list) { if (address.protocol() == QAbstractSocket::IPv4Protocol) return address.toString(); } return 0;}QString Widget::getUserName(){ QStringList envVariables; envVariables << "USERNAME.*" << "USER.*" << "USERDOMAIN.*" << "HOSTNAME.*" << "DOMAINNAM.*"; QStringList environment = QProcess::systemEnvironment(); foreach (QString string, environment) { int index = environment.indexOf(QRegExp(string)); if (index != -1) { QStringList stringList = environment.at(index).split('='); if (stringList.size() == 2) { return stringList.at(1); } } } return "unknown";}QString Widget::getMessage(){ QString msg = ui->messageTextEdit->toHtml(); ui->messageTextEdit->clear(); ui->messageTextEdit->setFocus(); return msg;}void Widget::on_sendButton_clicked(){ sendMessage(Message);}
main.cpp
#include "widget.h"#include <QApplication>int main(int argc, char *argv[]){ QApplication a(argc, argv); Widget w; w.show(); return a.exec();}注意:在qt中的信号与槽机制中,通过鼠标操作来关联槽,在生成的代码中是没有connect的,以按钮sendButton为例,生成的槽函数为on_sendButton_click(),当你在构造函数中再一次用connect关联时,会触发两次,导致会弹出“发送内容为空”的对话框。
0 0
- Qt的UDP编程
- QT 的UDP SOCKET编程
- qt编程:windows下的udp通信
- Qt下的tcp,udp编程
- QT的UDP通信编程实例
- QT网络编程-UDP
- QT之UDP编程
- QT中的UDP编程
- QT UDP网络编程
- Qt 网络编程-UDP
- qt-udp协议编程
- QT Socket编程--UDP Server
- QT 网络编程之udp
- Qt中的TCP/UDP编程
- [Qt学习篇]UDP编程
- QT:UDP网络编程实现
- QT中TCP UDP编程
- QT基于UDP通信的多线程编程问题
- c#做登陆界面
- 纯js实用DOM元素放大缩小特效插件
- 字节对齐
- 如果用代理在IE打开一个网页,怎么看这个网页的IP
- List、Map与Set集合
- Qt的UDP编程
- 关于安装Hadoop的Linux系统配置
- 蓝桥杯-入门训练-Fibonacci数列
- C++和PHP在面性对象特性上的对比
- Mysql 配置主从
- jQuery炫酷3d背景视觉差特效
- 第一节 Informatica 的 Visio 映射架构之 结构(二)
- 耐得住寂寞
- hdoj_2544 最短路