0

我正在为我的大学项目制作一个程序并且遇到了一些麻烦。我有一个名为“服务器”的进程正在启动其他一些名为“客户端”的进程。服务器进程可以读取和写入文件。客户端进程可以向服务器请求文件中的某篇文章,然后对其进行修改或读取。

我创建了一个匿名管道来在服务器和客户端之间共享文章,并将其写入和读取句柄放入每个客户端的命令行中,以便它可以对管道进行写入和读取。

问题是我无法从管道中读取信息。服务器:

#include <iostream>
#include <windows.h>
#include <string>
#include <fstream>
#include <string>
using namespace std;
struct clientData {
    HANDLE client;
    int operation;
    int studentNum;
};
struct Student
{
    int num;             
    string name;     
    double grade;       
    friend ostream& operator << (ostream& out, Student& item){
        out.write((char*)&item, sizeof Student);
        return out;
    }
};
struct serverData {
    HANDLE client;
    Student stud;
};
void main() {
    cout << "Enter the amount of students you want to input" << endl;
    int count;
    cin >> count;
    Student* students = new Student[count];
    for (int i = 0; i < count; i++)
    {
        cout << "Enter the num, name and grade for the " << i + 1 << ". student" << endl;
        cin >> students[i].num >> students[i].name >> students[i].grade;
    }
    ofstream outb("MyFile", iostream::binary);
    cout << "your binary file looks like" << endl;
    for (int i = 0; i < count; i++)
    {
        outb << students[i];
        cout << students[i];
    }
    cout <<endl  << "Enter the amount of clients" << endl;
    int processcount;
    cin >> processcount;
    STARTUPINFO si;
    PROCESS_INFORMATION piApp;
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    HANDLE  writepipe, readpipe, pipehandle, writtenClient,writtenserver,  dataready, mutex;
    writtenserver = CreateEvent(NULL, FALSE, FALSE, L"writtenServer");
    dataready = CreateEvent(NULL, FALSE, FALSE, L"dataready");
    CreatePipe(&readpipe, &writepipe, NULL, (sizeof HANDLE + sizeof Student));
    writtenClient = CreateEvent(NULL, FALSE, FALSE, L"writtenClient");
    for (int i = 0; i < processcount; i++)
    {
        CreateProcess(L"client\\Debug\\client.exe",(LPWSTR)(string(" ") + (char*)&writepipe + string(" ") + (char*)&readpipe).c_str() , NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &piApp);
    }
    clientData item;
    serverData serv;
    DWORD bytesRead;
    int num;
    mutex = CreateMutex(NULL, FALSE, L"currentClient");
    while (true) {
        WaitForSingleObject(writtenClient, NMPWAIT_WAIT_FOREVER);
        ReadFile(readpipe, (LPVOID)&item, sizeof clientData, NULL, NULL);
        num = item.operation;
        cout << " num" << endl;
        switch (item.operation) {
            case 1:{
                for (int i = 0; i < processcount; i++) {
                    if (students[i].num == item.studentNum) {
                        serv.client = item.client;
                        serv.stud = students[i];
                        WriteFile(writepipe, (LPCVOID)&serv, sizeof clientData, NULL, NULL);
                        SetEvent(writtenserver);
                        break;
                    }
                }
                WaitForSingleObject(dataready, NMPWAIT_WAIT_FOREVER);
                ReadFile(readpipe, (LPVOID)&serv, sizeof serverData, NULL, NULL);
                ReleaseMutex(mutex);
                break;
            }
            case 2:{}//Not Ready yet, i need to get the 1 working first
            default: {
                break;
            }
        }
    }
    for (int i = 0; i < count; i++)
    {
        cout << students[i];
    }
    system("pause");
}

客户:

#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
struct clientData {
    HANDLE client;
    int operation;
    int studentNum;
};
struct Student
{
    int num;               
    string name;     
    double grade;         
    friend ostream& operator << (ostream& out, Student& item) {
        out.write((char*)&item, sizeof Student);
        return out;
    }
};
struct serverData {
    HANDLE client;
    Student stud;
};
void main(int argc, char* argv[]) {
    cout << "started" << endl;
    system("pause");
    HANDLE clientHandle, writepipe, writtenClient, writtenServer, readpipe, dataready, mutex;
    clientData item;
    writtenClient = CreateEvent(NULL, FALSE, FALSE, L"writtenClient");
    writtenServer = OpenEvent(EVENT_MODIFY_STATE, FALSE, L"writtenServer");
    item.client = GetCurrentProcess();
    clientHandle = GetCurrentProcess();
    writepipe = (void*)(argv[1]);
    readpipe = (void*)(argv[2]);
    dataready = OpenEvent(EVENT_MODIFY_STATE, FALSE, L"dataready");
    mutex = OpenMutex(EVENT_MODIFY_STATE, FALSE, L"currentClient");
    int n = 0;
    DWORD bytesRead;
    serverData serv;
    while (n != 3) {
        cout << "Enter 1 to modify, 2 to read and 3 to exit" << endl;
        cin >> n;
        switch (n) {
        case 1: {
                WaitForSingleObject(mutex, NMPWAIT_WAIT_FOREVER);
                item.operation = 1;
                cout << "Enter the key to the studen(num)" << endl;
                cin >> item.studentNum;
                WriteFile(writepipe, (LPCVOID)&item, sizeof clientData, NULL, NULL);
                SetEvent(writtenClient);
                while (true) {
                    WaitForSingleObject(writtenServer, NMPWAIT_WAIT_FOREVER);
                    cout << "1 ";
                    ReadFile(readpipe, (LPVOID)&serv, sizeof serverData, NULL, NULL);
                    if (serv.client == clientHandle) {
                        break;
                    }
                }
                cout << serv.stud.name << endl << serv.stud.grade << endl << serv.stud.num << endl;
                cout << "Enter the students name and grade to modify" << endl;
                cin >> serv.stud.name >> serv.stud.grade;
                WriteFile(writepipe, (LPCVOID)&serv, sizeof clientData, NULL, NULL);
                SetEvent(dataready);
                break; 
            }
            case 2: { //I have to get 1 working first
                cout << "Enter the key to the studen(num)" << endl;
                cin >> item.studentNum;
                WriteFile(writepipe, (LPCVOID)&item, sizeof clientData, NULL, NULL);
                SetEvent(writtenClient);
                while (true) {
                    break;
                }
                break;
            }
            case 3: {
                cout << "Exitting..." << endl;
                break;
            }
            default: {
                cout << "Wrong input" << endl;
                break;
            }
        }
    }
    system("pause");
}

我知道这是大量的代码,但是这里的所有内容都对调试程序很有用。如果你有任何建议如何让它更漂亮写评论,我会解决的。

4

0 回答 0