Widget::Widget(QWidget*parent) :
QWidget(parent),
ui(newUi::Widget)
{
ui->setupUi(this);
udpSocket= new QUdpSocket(this);
port= 45454;
udpSocket->bind(port, QUdpSocket::ShareAddress |QUdpSocket::ReuseAddressHint);
connect(udpSocket, SIGNAL(readyRead()),this, SLOT(processPendingDatagrams()));
sendMessage(NewParticipant);//TcpServer是tcpserver.ui对应的类,上面直接用QUdpSocket是因为没有单独的udpserver.ui类 server = new TcpServer(this);//sendFileName()函数一发送,则触发槽函数getFileName() connect(server, SIGNAL(sendFileName(QString)), this, SLOT(getFileName(QString)));
}
Widget::~Widget()
{
delete ui;
}//使用UDP广播发送信息 voidWidget::sendMessage(MessageType type, QString serverAddress)
{
QByteArray data;
QDataStreamout(&data, QIODevice::WriteOnly);
QString localHostName=QHostInfo::localHostName();
QString address=getIP();out << type << getUserName() <
{caseMessage :if (ui->messageTextEdit->toPlainText() == "") {
QMessageBox::warning(0,tr("警告"),tr("发送内容不能为空"),QMessageBox::Ok);return;
}out << address <
ui->messageBrowser->verticalScrollBar()->setValue(ui->messageBrowser->verticalScrollBar()->maximum());break;caseNewParticipant :out <
userTableWidget->currentRow();//必须选中需要发送的给谁才可以发送 QString clientAddress = ui->userTableWidget->item(row, 2)->text();//(row,,2)为ip地址 out << address << clientAddress << fileName;//发送本地ip,对方ip,所发送的文件名 break;}caseRefuse :out <
}
udpSocket->writeDatagram(data,data.length(),QHostAddress::Broadcast, port);
}//接收UDP信息 voidWidget::processPendingDatagrams()
{while(udpSocket->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpSocket->pendingDatagramSize());
udpSocket->readDatagram(datagram.data(), datagram.size());
QDataStreamin(&datagram, QIODevice::ReadOnly);intmessageType;in >>messageType;
QString userName,localHostName,ipAddress,message;
QString time=QDateTime::currentDateTime()
.toString("yyyy-MM-dd hh:mm:ss");switch(messageType)
{caseMessage:in >> userName >> localHostName >> ipAddress >>message;
ui->messageBrowser->setTextColor(Qt::blue);
ui->messageBrowser->setCurrentFont(QFont("Times New Roman",12));
ui->messageBrowser->append("[" +userName+"]"+time);
ui->messageBrowser->append(message);break;caseNewParticipant:in >>userName >>localHostName >>ipAddress;
newParticipant(userName,localHostName,ipAddress);break;caseParticipantLeft:in >>userName >>localHostName;
participantLeft(userName,localHostName,time);break;caseFileName: {in >> userName >> localHostName >>ipAddress;
QString clientAddress, fileName;in >> clientAddress >>fileName;
hasPendingFile(userName, ipAddress, clientAddress, fileName);break;
}caseRefuse: {in >> userName >>localHostName;
QString serverAddress;in >>serverAddress;
QString ipAddress=getIP();if(ipAddress ==serverAddress)
{
server->refused();
}break;
}
}
}
}//处理新用户加入 voidWidget::newParticipant(QString userName, QString localHostName, QString ipAddress)
{bool isEmpty = ui->userTableWidget->findItems(localHostName, Qt::MatchExactly).isEmpty();if(isEmpty) {
QTableWidgetItem*user = newQTableWidgetItem(userName);
QTableWidgetItem*host = newQTableWidgetItem(localHostName);
QTableWidgetItem*ip = newQTableWidgetItem(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(tr("%1 在线!").arg(userName));
ui->userNumLabel->setText(tr("在线人数:%1").arg(ui->userTableWidget->rowCount()));
sendMessage(NewParticipant);
}
}//处理用户离开 voidWidget::participantLeft(QString userName, 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(tr("%1 于 %2 离开!").arg(userName).arg(time));
ui->userNumLabel->setText(tr("在线人数:%1").arg(ui->userTableWidget->rowCount()));
}//获取ip地址 QString Widget::getIP()
{
QListlist =QNetworkInterface::allAddresses();foreach(QHostAddress address, list) {if(address.protocol() ==QAbstractSocket::IPv4Protocol)returnaddress.toString();
}return 0;
}//获取用户名 QString Widget::getUserName()
{
QStringList envVariables;
envVariables<< "USERNAME.*" << "USER.*" << "USERDOMAIN.*" << "HOSTNAME.*" << "DOMAINNAME.*";
QStringList environment=QProcess::systemEnvironment();foreach (QString string, envVariables) {int index = environment.indexOf(QRegExp(string));if (index != -1) {
QStringList stringList= environment.at(index).split('=');if (stringList.size() == 2) {return stringList.at(1);break;
}
}
}return "unknown";
}//获得要发送的消息 QString Widget::getMessage()
{
QString msg= ui->messageTextEdit->toHtml();
ui->messageTextEdit->clear();
ui->messageTextEdit->setFocus();returnmsg;
}//发送消息 voidWidget::on_sendButton_clicked()
{
sendMessage(Message);
}//获取要发送的文件名 voidWidget::getFileName(QString name)
{
fileName=name;
sendMessage(FileName);
}//传输文件按钮 voidWidget::on_sendToolBtn_clicked()
{if(ui->userTableWidget->selectedItems().isEmpty())//传送文件前需选择用户 {
QMessageBox::warning(0, tr("选择用户"),
tr("请先从用户列表选择要传送的用户!"), QMessageBox::Ok);return;
}
server->show();
server->initServer();
}//是否接收文件,客户端的显示 voidWidget::hasPendingFile(QString userName, QString serverAddress,
QString clientAddress, QString fileName)
{
QString ipAddress=getIP();if(ipAddress ==clientAddress)
{int btn = QMessageBox::information(this,tr("接受文件"),
tr("来自%1(%2)的文件:%3,是否接收?")
.arg(userName).arg(serverAddress).arg(fileName),
QMessageBox::Yes,QMessageBox::No);//弹出一个窗口 if (btn ==QMessageBox::Yes) {
QString name= QFileDialog::getSaveFileName(0,tr("保存文件"),fileName);//name为另存为的文件名 if(!name.isEmpty())
{
TcpClient*client = new TcpClient(this);
client->setFileName(name); //客户端设置文件名 client->setHostAddress(QHostAddress(serverAddress)); //客户端设置服务器地址 client->show();
}
}else{
sendMessage(Refuse, serverAddress);
}
}
}