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