Can't read/write from/to anonymous pipe

658 Views Asked by At

I am making a programm for my University project and having some troubles. i have a process called "Server" that is starting some other processes called "clients". the Server process can read and write from a file. The client processes can ask the server for a certain article in the file and then modify or read it.

i create a anonymous pipe to share articles between the Server and the clients and putting it write and read handle into the command line of every client, so it can write and read to the pipe.

The problem is i can not read information from the pipe. Server:

#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");
}

Client:

#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");
}

I Understand that this is a big amount of code, but everything here is useful to debug the program. If u have any suggestions how to make it more beautiful write a comment, i will fix that.

0

There are 0 best solutions below