0

I'm trying to make a simple client-server program using windows file mapping and that uses semaphores. The clients send to the server 2 numbers, the server computes nr1+nr2 and nr1 * nr2. I tried something but it doesn't even work for 1 client and I want it to work for more clients. Here's the code:

the server:

#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;

typedef struct {
    int nr1;
    int nr2;
} Mesaj;

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

    Mesaj* mesaj;

    HANDLE createSemaphore = CreateSemaphore(NULL, 1, 1, "Semafor");
    if (createSemaphore == NULL || createSemaphore == INVALID_HANDLE_VALUE) {
        wcout << "Failed to create a semaphore\n";
    } else {
        wcout << "Created the semaphore\n";
    }

    HANDLE hMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
            PAGE_READWRITE, 0, sizeof(Mesaj), "SharedMemory");

    WaitForSingleObject(createSemaphore, INFINITE);

    mesaj = (Mesaj*) MapViewOfFile(hMemory, FILE_MAP_READ, 0, 0, sizeof(Mesaj));

    printf("The numbers received are: %d, %d\n", mesaj->nr1, mesaj->nr2);

    int produs = mesaj->nr1 * mesaj->nr2;
    int suma = mesaj->nr1 + mesaj->nr2;

    printf("\nSuma numerelor este: %d iar produsul lor este: %d", suma, produs);

    ReleaseSemaphore(createSemaphore, 1, NULL);

    Sleep(INFINITE);

    return 0;
}

the client:

#include <windows.h>
#include <stdio.h>
#include <iostream>
using namespace std;

typedef struct {
    int nr1;
    int nr2;
} Mesaj;

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

    Mesaj* mesaj, *mesaj2;

    mesaj2 = (Mesaj*) malloc(sizeof(Mesaj));

    HANDLE hMemory = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE,
            "SharedMemory");

    if (hMemory == NULL) {
        wcout << "Error at OpenFileMapping\n";
    }

    HANDLE openSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS,TRUE,"Semafor");
    if(openSemaphore != NULL || openSemaphore != INVALID_HANDLE_VALUE){
        wcout<<"the semaphore is opened\n";
    }

    mesaj2 = (Mesaj*) MapViewOfFile(hMemory, FILE_MAP_WRITE, 0, 0,
            sizeof(Mesaj));

    int nr1 = 0, nr2 = 0;
    printf("Give a number: ");
    scanf("%d", &nr1);
    printf("Give another number: ");
    scanf("%d", &nr2);

    mesaj2->nr1 = nr1;
    mesaj2->nr2 = nr2;

    if (mesaj2 == NULL) {
        wcout << "Error\n"
    } else {
        wcout << "I sent " << mesaj2->nr1 << " and " << mesaj2->nr2 << endl;
    }


    system("pause");
    return 0;
}

What exactly am I doing wrong? How should I work with semaphores?

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
MathMe
  • 101
  • 5
  • 13
  • 1
    Please be more specific what you mean by "doesn't work". For one thing, it doesn't appear that you ever signal the semaphore. For another thing, the server exits after it gets one messages. For a third thing, the two clients are modifying the same memory, which can result in data corruption. – Raymond Chen Oct 23 '13 at 17:41
  • Doesn't work because when I open the server it doesn't wait for the client to send the numbers and after that it doesn't do anything. – MathMe Oct 23 '13 at 17:44
  • If the problem is that the `WaitForSingleObject` returns without waiting, then say that, and delete all the shared memory stuff since it is not relevant to your problem. See http://sscce.org/ – Raymond Chen Oct 23 '13 at 19:00
  • You need more than one synchronization object here. One to ensure that only one process can access the MMF at the same time. You took care of that although you forgot to call WFSO in the client. If you also need a "client has updated the data" handshake then that requires additional synchronization. MMFs are very low-level, a pipe is often much easier to get going. – Hans Passant Oct 23 '13 at 19:09

1 Answers1

7

When I open the server it doesn't wait for the client.

The documentation for CreateSemaphore says

The state of a semaphore object is signaled when its count is greater than zero, and nonsignaled when its count is equal to zero. The lInitialCount parameter specifies the initial count.

You passed lInitialCount=1 when you created the semaphore. and 1 > 0, so the semaphore is signaled and the WaitForSingleObject returns immediately.

You presumably want to create the semaphore with an initial count of 0, so that it does not become signaled until somebody calls ReleaseSemaphore.

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135