Diskuze: Komunikace pomocí rour - windows

C++ C a C++ Komunikace pomocí rour - windows

Avatar
švrčajs
Člen
Avatar
švrčajs:

Zdravím, řeším komunikací pomocí rour(pipe), má se jednat o server a klienta, klient posílá čísla a operátory, pak postupně počítá, to je v celku jedno teď. Narazil jsem na problém už při samotné komunikaci. Když serveru pošlu poprvé data, tak se vypíšou, ale pak to hned hodí error. Určitě bude chyba v tom, že ten server nepočká na další data a pokračuje dál ve smyčce, narazí na if, který ho ukončí. A s tím bych potřeboval pomoct, jak udělat, aby počkal a nešel hned dál... S rourama pracuji poprvé a tak v tom plavu :D
¨
server:

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <stack>
#include <iostream>
#define BUFFER_SIZE 512
#define _CRT_SECURE_NO_WARNINGS



int _tmain(int argc, _TCHAR* argv[])
{
        std::stack<int> zasobnik;
        BOOL fSuccess;
        char buffer[BUFFER_SIZE];
        //vytvoreni roury
        HANDLE hKalkulator;
        LPTSTR Kalkulator = TEXT("\\\\.\\pipe\\Kalkulator");
        hKalkulator = CreateNamedPipe(
                Kalkulator,
                PIPE_ACCESS_DUPLEX,
                PIPE_TYPE_MESSAGE |
                PIPE_READMODE_MESSAGE |
                PIPE_WAIT,
                PIPE_UNLIMITED_INSTANCES,
                BUFFER_SIZE,
                BUFFER_SIZE,
                NMPWAIT_USE_DEFAULT_WAIT,
                NULL);

        if (INVALID_HANDLE_VALUE == hKalkulator)
        {
                printf("Nejde vytvorit roura\n");
                system("pause");
                return -1;
        }
        else
        {
                printf("Roura vytvorena\nCekani na hosta\n");
        }
        BOOL connected = ConnectNamedPipe(hKalkulator, NULL);
        if (connected)
        {
                printf("klient pripojen\n");
        }
        else
        {
                printf("potize s pripojenim klienta\n");
        }
        // komunikce if # konec, čísla na zásobník, operátory + - * / %
        //první číslo pravý operand druhé levý, odebrat ze zásobníků, pak pop výsledek
        while (connected)
        {
                //čtení pm od klienta
                DWORD bytes;
                fSuccess = ReadFile(
                        hKalkulator,
                        buffer,
                        sizeof(buffer),
                        &bytes,
                        NULL);


                if ((fSuccess) || (0 == bytes))
                {
                        printf("Nelze cist z roury\n");
                        CloseHandle(hKalkulator);
                        system("pause");
                        return -1;
                }
                else
                {
                        printf("\n%s\n", buffer);
                }

                /*else
                {
                        int x = 0;
                        int pravyOperand = 0, levyOperand = 0, vypocet = 0;
                        if (buffer[0] == '*')
                        {
                                pravyOperand = zasobnik.top();
                                zasobnik.pop();
                                levyOperand = zasobnik.top();
                                zasobnik.pop();
                                vypocet = levyOperand * pravyOperand;
                                zasobnik.push(vypocet);
                        }
                        else if (buffer[0] == '+')
                        {
                                pravyOperand = zasobnik.top();
                                zasobnik.pop();
                                levyOperand = zasobnik.top();
                                zasobnik.pop();
                                vypocet = levyOperand + pravyOperand;
                                zasobnik.push(vypocet);
                        }
                        else if (buffer[0] == '-')
                        {
                                pravyOperand = zasobnik.top();
                                zasobnik.pop();
                                levyOperand = zasobnik.top();
                                zasobnik.pop();
                                vypocet = levyOperand - pravyOperand;
                                zasobnik.push(vypocet);
                        }
                        else if (buffer[0] == '/')
                        {
                                pravyOperand = zasobnik.top();
                                zasobnik.pop();
                                levyOperand = zasobnik.top();
                                zasobnik.pop();
                                vypocet = levyOperand / pravyOperand;
                                zasobnik.push(vypocet);
                        }
                        else if (buffer[0] == '%')
                        {
                                pravyOperand = zasobnik.top();
                                zasobnik.pop();
                                levyOperand = zasobnik.top();
                                zasobnik.pop();
                                vypocet = levyOperand % pravyOperand;
                                zasobnik.push(vypocet);
                        }
                        else if (buffer[0] == '#')
                        {
                                CloseHandle(hKalkulator);
                                break;
                                system("pause");
                        }
                        else
                        {
                                x = atoi(strtok(buffer, '\0'));
                                if (sizeof(zasobnik) < 20)
                                {
                                        zasobnik.push(x);
                                }
                        }
                }*/

        }
        return 0;
}

klient

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>

#define BUFFER_SIZE 512

int _tmain(int argc, _TCHAR* argv[])
{
        char buffer[BUFFER_SIZE];

        HANDLE hKalkulator;
        LPTSTR Kalkulator = TEXT("\\\\.\\pipe\\Kalkulator");
        BOOL fSuccess = FALSE;
        DWORD cbToWrite, cbWritten, dwMode;
                hKalkulator = CreateFile(
                        Kalkulator,
                        GENERIC_READ |
                        GENERIC_WRITE,
                        0,
                        NULL,
                        OPEN_EXISTING,
                        0,
                        NULL);




        while (1)
        {
                scanf("%s", &buffer);
                cbToWrite = (sizeof(buffer) + 1)*sizeof(TCHAR);
                fSuccess = WriteFile(
                        hKalkulator,                  // pipe handle
                        buffer,             // message
                        cbToWrite,              // message length
                        &cbWritten,             // bytes written
                        NULL);

        }




        system("pause");

        return 0;
}

Kouknete na to někdo prosím ?

 
Odpovědět 10.12.2015 15:15
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na švrčajs
Martin Dráb:

No, ve smyčce na serveru napřed zavoláš ReadFile a jeho výsledek uložíš do proměnné fSuccess... no a pak máš podmínku, která je splněna, když fSuccess je TRUE (ReadFile uspěla). A následkem je, že napíšeš, že nelze číst z roury, zavřeš k ní handle a ukončíš program. Což asi nechceš.

Jinak, pokud není co z roury načíst, ReadFile bude blokující; bude čekat, dokud požadovaný počet bajtů nepřiteče.

Nahoru Odpovědět 10.12.2015 18:16
2 + 2 = 5 for extremely large values of 2
Avatar
švrčajs
Člen
Avatar
Odpovídá na Martin Dráb
švrčajs:

No, upravil jsem to na:

while (true)
        {
                //čtení pm od klienta
                DWORD bytes;
                fSuccess = ReadFile(
                        hKalkulator,
                        buffer,
                        sizeof(buffer),
                        &bytes,
                        NULL);
                if (!fSuccess)
                {
                        printf("\n%s\n", buffer);
                }
        }

a pomocí debugu, jsem si to odkrokoval.. pošlu písmeno, písmeno se uloží do bufferu, ten se vytiskne a mělo by to teda čekat na další data, jenže se while ještě jednou projede, vypíše klikyháky a pak teprve čeká na další data.
Takže výstup je pak vypsané písméno a pod tím čínské znaky :D a to nevím, kde se tam bere.. :D

Editováno 10.12.2015 18:41
 
Nahoru Odpovědět 10.12.2015 18:39
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na švrčajs
Martin Dráb:

V rámci jednoho volání zapisuješ (sizeof(buffer) + 1)*sizeof(TCHAR) bajtů. V rámci jednoho čtení čteš sizeof(buffer) bajtů. Což s sebou nese několik problémů:

  1. čteš méně dat, než zapisuješ (což hádám, že nechceš),
  2. jestli sizeof(TCHAR) = 2, tak zapíšeš dost dat na to, aby nasytila dvě čtení. A ano, to druhé ti dá klikyháky, mj. protože
  3. zapisuješ data z buffer, který je ale menší než množství zapisovaných dat, takže tam přijdou i klikyháky, a to i kdybys ten buffer na začátku vynuloval.
Nahoru Odpovědět 10.12.2015 19:10
2 + 2 = 5 for extremely large values of 2
Avatar
švrčajs
Člen
Avatar
Odpovídá na Martin Dráb
švrčajs:

Díky, nechápu, že mi to nedošlo už dřív... jsem to ale vůl :D

 
Nahoru Odpovědět 10.12.2015 19:18
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na švrčajs
Martin Dráb:

Nemyslím... minimálně u mě platí taková přímá úměra: čím déle nějakou chybu hledám, tím větší blbost to je :-).

Nahoru Odpovědět 10.12.2015 19:29
2 + 2 = 5 for extremely large values of 2
Avatar
švrčajs
Člen
Avatar
Odpovídá na Martin Dráb
švrčajs:

Já nad tím přemýšlel od rána, takže ta úměra platí ;)

 
Nahoru Odpovědět 10.12.2015 19:32
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.