2013-11-21 3 views
0

Qt를 사용하여 채팅 프로그램을 작성하려고합니다. 절반 정도 완성되었지만 몇 가지 문제가 있습니다.C++/Qt의 UDP 서버 - 클라이언트 채팅

먼저 클라이언트에게 내 서면 메시지를 lineedit으로 보낼 때 오류가 발생합니다. QString이지만 writeDatagramQByteArray 만 보냅니다. 나는 그것을 봤 거든 거기에 QStringQByteArray로 변환하는 몇 가지 방법이 있지만 더 나은 솔루션을 찾고 있어요. connectToHost()을 사용해야한다고 생각하지만 read()write()은 작동하지 않습니다.

두 번째로 중요한 문제는 계속해서 메시지를 보내고받을 수 없다는 것입니다. 분명히이 문제는 아직 발생하지 않았지만 Qt 콘솔에서 테스트했기 때문에 문제가 있다는 것을 알고 있습니다.

GUI 및 소켓 프로그래밍에 익숙하지 않으므로이 주제를 게시하기 전에 많은 내용을 검색했습니다.

업데이트 : 내 첫 번째 문제는 해결되었지만 이제 UDP 패킷은 채팅 응용 프로그램처럼 작동하지 않고 보내고받을 수 있습니다.

업데이트 : 문제점을 발견하고 해결했습니다. 코드에는 두 개의 QUdpSocket 개체가 필요합니다. 나는 또한 코드를 업데이트했다. 이제 완전히 기능적입니다. 다른 입력 사항이 있으면 듣고 싶습니다. 그렇지 않으면 답을 얻었습니다.

서버 :

#include "schat.h" 
#include "ui_schat.h" 

schat::schat(QWidget *parent) : 
    QWidget(parent), 
    ui(new Ui::schat) 
{ 
    ui->setupUi(this); 
    socketServerc=new QUdpSocket(this); 
    socketServer=new QUdpSocket(this); 
    socketServer->bind(QHostAddress::LocalHost, 8001); 
    connect(socketServer,SIGNAL(readyRead()),this,SLOT(readPendingDatagrams())); 

} 

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

void schat::on_sendButton_clicked() 
{ 


    QString word=ui->lineEdit->text(); 
    ui->textBrowser->append(word); 
    QByteArray buffer; 
    buffer=word.toUtf8(); 
    QHostAddress sender; 
    quint16 senderPort; 
    socketServerc->writeDatagram(buffer.data(), QHostAddress::LocalHost, 7000); 

} 

void schat::readPendingDatagrams() 
{ 
    while (socketServer->hasPendingDatagrams()) { 
     QByteArray buffer; 
     buffer.resize(socketServer->pendingDatagramSize()); 
     QHostAddress sender; 
     quint16 senderPort; 
     socketServer->readDatagram(buffer.data(), buffer.size(),&sender, &senderPort); 
     ui->textBrowser->append(buffer.data()); 

    } 

} 

클라이언트하십시오 QByteArray에 QString 변환은

#include "uchat.h" 
#include "ui_uchat.h" 


uchat::uchat(QWidget *parent) : 
    QWidget(parent), 
    ui(new Ui::uchat) 
{ 
    ui->setupUi(this); 
    clientSocket=new QUdpSocket(this); 
    clientSocketc=new QUdpSocket(this); 
    clientSocketc->bind(QHostAddress::LocalHost, 7000); 
    connect(clientSocketc,SIGNAL(readyRead()),this,SLOT(readPendingDatagrams())); 
} 

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

void uchat::on_sendButton_clicked() 
{ 
    QString word=ui->lineEdit->text(); 
    ui->textBrowser->append(word); 
    QByteArray buffer; 
    buffer.resize(clientSocket->pendingDatagramSize()); 
    QHostAddress sender; 
    quint16 senderPort; 
    buffer=word.toUtf8(); 
    clientSocket->writeDatagram(buffer.data(), QHostAddress::LocalHost, 8001); 
} 
void uchat::readPendingDatagrams() 
{ 
    while (clientSocketc->hasPendingDatagrams()) { 
     QByteArray buffer; 
     buffer.resize(clientSocketc->pendingDatagramSize()); 
     QHostAddress sender; 
     quint16 senderPort; 
     clientSocketc->readDatagram(buffer.data(), buffer.size(),&sender, &senderPort); 
     ui->textBrowser->append(buffer.data()); 

    } 

} 

답변

2

실제로 할 수있는 일이다. 그 이유는 UDP 패킷이 일련의 바이트만을 전달하기 때문입니다. 그러나 QString은 명백하게 바이트 시퀀스를 나타내지 않습니다. 이것은 일련의 개념적 문자 (a.k.a. QChars)를 나타냅니다. 따라서 QString을 바이트 배열에 배치하려면 인코딩 할 바이너리 표현을 결정해야합니다. 예를 들어 UTF8 인코딩 (권장)을 사용하여 문자열을 인코딩하려면 QString의 toUtf8() 메서드를 사용하여 UTF8 인코딩을 나타내는 QByteArray를 가져오고 수신기는 QString의 fromUtf8() 메서드를 사용하여 수신 된 바이트를 QString으로 되돌립니다. 다른 인코딩 (ascii, latin1, local8Bit)도 있지만 UTF8뿐 아니라 국제화도 처리하지 못할 수 있습니다.

두 번째 문제 ("나는 계속해서 메시지를 보내고받을 수 없음")에 대해 일어날 일과 일어난 일에 대해보다 명확하고 설명이 있어야합니다. 나는이 문맥에서 "연속적으로"무엇을 의미하는지 모른다.

+0

@ Jermer Friesner 늦게 답변드립니다. 첫 번째 문제가 해결되어 주셔서 감사합니다. 이제는 오류가 발생하지 않습니다. 그러나 서버와 클라이언트는 단순히 통신하지 않습니다. 서버 채팅 박스에는 "Hello! from client"라는 문자가 표시됩니다. UDP 패킷은 전송되지 않으며 이유를 알지 못합니다. 모든 것은 나와 함께 괜찮아 보인다. – Arwen

+0

@Jeremey Friesner 다시 한 번 감사드립니다. 내가 처음에 그걸 어떻게 놓쳤는지 모르겠다. 이제 문제를 해결 한 후 내 코드가 제대로 작동합니다. – Arwen