• 6224阅读
  • 3回复

使用QUdpSocket实现简单的聊天程序中碰到的问题 [复制链接]

上一主题 下一主题
离线baggioyao
 
只看楼主 倒序阅读 楼主  发表于: 2010-05-03
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
我想要实现一个简易的聊天程序,用UDP实现。
下面是源码:

界面:textEdit_record是显示聊天记录的区域,textEdit_send是消息输入框,pushButton_send是发送按钮,pushButton_close是关闭按钮。

//****************
// myqq.h
//****************
#ifndef MYQQ_H
#define MYQQ_H

#include <QMainWindow>
#include <QUdpSocket>

namespace Ui {
  class MyQQ;
}

class MyQQ : public QMainWindow {
  Q_OBJECT
public:
  MyQQ(QWidget *parent = 0);
  ~MyQQ();

protected:
  void changeEvent(QEvent *e);

private:
  Ui::MyQQ *ui;
  QUdpSocket udpSocket;
// QUdpSocket udp_receive;

private slots:
  void on_pushButton_close_clicked();
  void on_pushButton_send_clicked();
  void receiveDataGram();
};

#endif // MYQQ_H

//*******************
// myqq.cpp
//*******************
#include "myqq.h"
#include "ui_myqq.h"
#include <QByteArray>

MyQQ::MyQQ(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MyQQ)
{
  ui->setupUi(this);
  udpSocket.bind(5824);
  connect(&udpSocket, SIGNAL(readyRead()), this, SLOT(receiveDataGram()));
}

MyQQ::~MyQQ()
{
  delete ui;
}

void MyQQ::changeEvent(QEvent *e)
{
  QMainWindow::changeEvent(e);
  switch (e->type()) {
  case QEvent::LanguageChange:
  ui->retranslateUi(this);
  break;
  default:
  break;
  }
}

void MyQQ::on_pushButton_send_clicked()
{
  QByteArray datagram;
  QDataStream out(&datagram, QIODevice::WriteOnly);
  out.setVersion(QDataStream::Qt_4_6);
  out << ui->textEdit_send->toPlainText();
// ui->textEdit_record->append(ui->textEdit_send->toPlainText());
  ui->textEdit_send->clear();
  udpSocket.writeDatagram(datagram, QHostAddress::LocalHost, 5824);
}

void MyQQ::receiveDataGram()
{
  QByteArray datagram;
  do{
  datagram.resize(udpSocket.pendingDatagramSize());
  udpSocket.readDatagram(datagram.data(), datagram.size());
  }while(udpSocket.hasPendingDatagrams());

  QString text_rcv;
  QDataStream in(&datagram, QIODevice::ReadOnly);
  in >> text_rcv;

  ui->textEdit_record->append("<font color=green> server : </font>" + text_rcv);
}

void MyQQ::on_pushButton_close_clicked()
{
  close();
}

问题:运行两次该程序,按照打开的顺序依次叫A和B(A先打开)。运行发现在A中发送消息给B时A的消息记录框显示发送的消息,B的消息记录框中不显示;在 B中发送给A时也是只有A的消息记录框显示信息,B自己的不显示。
调试发现:在A中发送消息给B时(即在执行完A的 udpSocket.writeDatagram(datagram, QHostAddress::LocalHost, 5824);这句以后,程序时跑到了A程序的receiveDataGram(),而不是B程序的receiveDataGram();在B中发送给A时是正常的,也就是执行完B的udpSocket.writeDatagram(datagram, QHostAddress::LocalHost, 5824);这句以后,跳到A的receiveDataGram()处执行。
请问这是什么原因,是不是跟线程有关?怎么解决之?
离线paranoid
只看该作者 1楼 发表于: 2010-05-04
同一台机器里的一个端口号不能绑定两次,第二次B执行udpSocket.bind(5824);将会失败,因为已经被A占用,所以只有A能接收。
离线paranoid
只看该作者 2楼 发表于: 2010-05-04
看了下文档,也是可以共享的,绑定模式设置为QUdpSocket::ShareAddress,这种用法相当于实现了一个负载均衡
离线baggioyao
只看该作者 3楼 发表于: 2010-05-04
引用第2楼paranoid于2010-05-04 09:50发表的  :
看了下文档,也是可以共享的,绑定模式设置为QUdpSocket::ShareAddress,这种用法相当于实现了一个负载均衡

恩,多谢!
快速回复
限100 字节
 
上一个 下一个