C++ 服务器不从客户端读取数据

C++ 服务器不从客户端读取数据,c++,qt,winapi,qt5,named-pipes,C++,Qt,Winapi,Qt5,Named Pipes,程序要点:服务器创建n个客户端进程。在客户机上,用户输入发送到服务器的字符串。在服务器上,字符串的处理如下:计算输入字符串中元音和数字的出现频率。然后将此信息发送到客户端 两个程序(服务器和客户端)基于控制台版本(它们工作得非常好)。当我向服务器添加QT支持时,控制台客户端和gui服务器工作正常,但当我向客户端添加gui时,它停止工作,我不知道该做什么。 我想问题甚至不在于命名管道,而在于Qt(在客户端)方面的笨拙代码。客户端输出到服务器的连接已建立,服务器指示它无法从管道中读取字符串。 服务器

程序要点:服务器创建n个客户端进程。在客户机上,用户输入发送到服务器的字符串。在服务器上,字符串的处理如下:计算输入字符串中元音和数字的出现频率。然后将此信息发送到客户端

两个程序(服务器和客户端)基于控制台版本(它们工作得非常好)。当我向服务器添加QT支持时,控制台客户端和gui服务器工作正常,但当我向客户端添加gui时,它停止工作,我不知道该做什么。 我想问题甚至不在于命名管道,而在于Qt(在客户端)方面的笨拙代码。客户端输出到服务器的连接已建立,服务器指示它无法从管道中读取字符串。 服务器可以创建n个gui客户端,然后,当我尝试向客户端写入字符串时,客户端关闭

客户代码:

gui_pipe_client.h:

#pragma once

#include <LotsOfLibraries...>

class Window : public QWidget {

Q_OBJECT // этот макрос должен включаться в классы, которые объявляют свои собственные сигналы и слоты

private:
  HANDLE. m_hndlNP;

public:
  Window(QWidget *parent = 0, HANDLE m_hndlNP = NULL);

private slots:
  int OnSend();

private:

  QLabel *lbl;
  QLineEdit *textfield;
  QPushButton *button_send;
};
#pragma一次
#包括
类窗口:公共QWidget{
质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标/质量目标
私人:
HANDLE.m_hndlNP;
公众:
窗口(QWidget*parent=0,句柄m_hndlNP=NULL);
专用插槽:
int OnSend();
私人:
QLabel*lbl;
QLineEdit*文本字段;
QPushButton*按钮发送;
};
gui_pipe_client.cpp:

#include "gui_pipe_client.h"

#include <QGridLayout>
#include <thread> //!NEW!

using namespace std;

#define PIPE_TIMEOUT 5000
#define BUFSIZE 4096


Window::Window(QWidget *parent, HANDLE hndlNP)
    : QWidget(parent), m_hndlNP(hndlNP){


QLineEdit *textfield = new QLineEdit(this);
textfield->setPlaceholderText("Enter string...");



QPushButton *button_send = new QPushButton("Send", this);

QPushButton *button_quit = new QPushButton("Quit", this);

lbl = new QLabel("kjiqofj13fjio2;3fjl;3jiofj2l3;fij3;fioj423j;fj32jf;o3f", this);
lbl->setWordWrap(true);

    QGridLayout *grid = new QGridLayout(this);
    grid->addWidget(textfield, 0, 0);
    grid->addWidget(button_send, 1, 0);
    grid->addWidget(button_quit, 2, 0);
    grid->addWidget(lbl, 3, 0);

  setLayout(grid);

 connect(button_send, &QPushButton::clicked, this, &Window::OnSend); // привязка сигнала и слота
 connect(button_quit, &QPushButton::clicked, qApp, &QApplication::quit); // signal - slot
}

int Window::OnSend() {

button_send->setEnabled(false);



    char text[1024];

    

    const QByteArray stringData = textfield->text().toUtf8();
    //char text[100];
    text[qMin(1023,stringData.size())]='\0';
    std::copy(stringData.constBegin(),stringData.constBegin()+qMin(1023,stringData.size()),text);

    printf("%s", text);
    

    
    char answer[1024];
    DWORD read_bytes;
    DWORD written_bytes;

    if (WriteFile(m_hndlNP, text, 1024, &written_bytes, NULL)) {

        if (!ReadFile(m_hndlNP, answer, 1024, &read_bytes, NULL)) {
            //printf("ReadFile failed with %d.\n", GetLastError());
            system("pause"); // TEMPORARY
            //return EXIT_FAILURE;
        }
    }
    else {
        printf("WriteFile failed with %d.\n", GetLastError());
        system("pause"); // TEMPORARY
        //return EXIT_FAILURE;
    }
    //cout << "Writting and reading was successful\n";

    
    lbl->setText((QString) (answer));
    
    // ***CLOSING PIPE CONNECTION***
    CloseHandle(m_hndlNP);

    
    //QApplication::quit();
    }
#包括“gui_pipe_client.h”
#包括
#包括/!新的!
使用名称空间std;
#定义管道超时5000
#定义BUFSIZE 4096
窗口::窗口(QWidget*父对象,句柄hndlNP)
:QWidget(父),m_hndlNP(hndlNP){
QLineEdit*textfield=新的QLineEdit(此);
text字段->设置占位符文本(“输入字符串…”);
QPushButton*button_send=新的QPushButton(“发送”,此项);
QPushButton*button_quit=新的QPushButton(“退出”,这是);
lbl=新的QLabel(“kjiqofj13fjio2;3fjl;3jiofj2l3;fij3;fioj423j;fj32jf;o3f”,本);
lbl->setWordWrap(真);
QGridLayout*grid=新的QGridLayout(本);
grid->addWidget(文本字段,0,0);
grid->addWidget(按钮发送,1,0);
grid->addWidget(按钮退出,2,0);
网格->添加小部件(lbl,3,0);
设置布局(网格);
连接(按钮发送,&QPushButton::点击,此,&Window::打开);//Пзззааааааа
连接(按钮退出,&QPushButton::clicked,qApp,&QApplication::退出);//信号-插槽
}
int Window::OnSend(){
按钮发送->设置启用(假);
字符文本[1024];
const QByteArray stringData=textfield->text().toUtf8();
//字符文本[100];
text[qMin(1023,stringData.size())]='\0';
std::copy(stringData.constBegin(),stringData.constBegin()+qMin(1023,stringData.size()),text);
printf(“%s”,文本);
字符应答[1024];
DWORD读取字节;
DWORD写入字节;
if(WriteFile(m_hndlNP,text,1024,&writed_字节,NULL)){
if(!ReadFile(m_hndlNP,answer,1024,&read_字节,NULL)){
//printf(“读取文件失败,错误为%d。\n”,GetLastError());
系统(“暂停”);//临时
//返回退出失败;
}
}
否则{
printf(“WriteFile失败,错误为%d。\n”,GetLastError());
系统(“暂停”);//临时
//返回退出失败;
}
//coutsettext((QString)(答案));
//***关闭管道连接***
闭合手柄(m_hndlNP);
//QApplication::quit();
}
main.cpp:

#include "gui_pipe_client.h"

using namespace std;

int main(int argc, char *argv[]) {

cout << "Client is launched\n";

    HANDLE hndlNP = CreateFile(
        TEXT("\\\\.\\pipe\\os_lab4_pipe"),
        GENERIC_READ | GENERIC_WRITE,
        NULL, // Prevents other processes from opening a file or device
        NULL, // cannot be inherited by any child processes
        OPEN_EXISTING,
        NULL, // no attributes
        NULL // no template
        );
    if (hndlNP == INVALID_HANDLE_VALUE) {
        printf("CreateFile error\n");
        cout << "CreateFile error\n";
        //return EXIT_FAILURE;
    }
    cout << "Pipe connection established\n";
    QApplication app(argc, argv);


    Window window(0, hndlNP);

    window.resize(600, 600);
    window.setWindowTitle("Pipe client");
    window.show();

    return app.exec();
}
#包括“gui_pipe_client.h”
使用名称空间std;
int main(int argc,char*argv[]){

如果您在通信方面遇到问题,请备份代码并删除所有GUI内容。这只是增加了隐藏bug的噪音。您是否有意在
窗口::OnSend()末尾调用
CloseHandle(m_hndlNP);
method?这似乎是客户端连接关闭的原因之一,不是吗?@JeremyFriesner,
CloseHandle(m_hndlNP);
位于写入服务器后
if(WriteFile(m_hndlNP,text,1024,&writed_字节,NULL)){/code>和从服务器读取
if(!ReadFile(m_hndlNP,answer,1024,&read字节,NULL)){
。所以lbl应该在gui客户端上显示来自服务器的应答,但我的程序在我按下“发送”按钮后崩溃,而且,客户端通过通道建立了连接,服务器写入了从指定管道(从客户端)读取字符串的失败消息。客户端是一次性的,仅用于1次字符串写入。