Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проецируемые файлы (клиент - сервер) 
:(
    Опции темы
koster26
Дата 10.5.2010, 07:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 7.12.2008

Репутация: нет
Всего: нет



Всем привет!
Есть 2 приложения (клиент и сервер), реализованных на базе именованных конвейеров(далее ИК) !

Суть программы: Клиент принимает от пользователя 2 комплексных числа и код операции(+, -, *, /).
Сервер принимает числа и код операции, выполняет ее, и выводит результат на экран.

Проблема: На базе ИК прогу реализовать удалось, но с отображаемыми файлами возникла проблема. Если механизм синхронизации на базе событий еще понятен, то механизм маршаллинга(я так понял, что он здесь нужен) я реализовать не могу(не получается упаковать массив структур).

Просьба: Помочь переделать клиент и сервер из ИК в отображаемые файлы.

Код сервера:
Код

#include "stdafx.h"
#include <iostream>
#include <process.h>
#include <stdio.h>
#include <windows.h>
#include <string>

#define MAX_STRUCT_SIZE             2

#define COMPLEX_NUMBER_SEPARATOR    "i"
#define PLUS                        "+"

using namespace std;

void AddingComplexNumbers(void);
void SubtractionComplexNumbers(void);
void MultipleComplexNumbers(void);
void DivisionComplexNumbers(void);
void OutputResults(string, float, float);
static unsigned __stdcall ThreadProcedure(LPVOID);

typedef struct
{
    float m_real;
    float m_imaginary;
    int m_codeOfOperation;
} TComplex;

TComplex g_ComplexNumbers[MAX_STRUCT_SIZE];

////////////////////////////////////////////////////////////////////////////////
//
//  Главная функция консольного приложения
//
//  FUNCTION: int main(void)
//
//  PARAMETERS: нет
//
//  RETURN VALUE: нет
//
//  COMMENTS: нет
//
void main(void)
{
    setlocale(LC_ALL, "Russian");
    HANDLE SingleNamedPipe;
    HANDLE hThread;
    BOOL fConnected;
    const int waitingTime = 5000;
    
    cout << "Сервер запущен и ждет подключения клиента" << endl;
    while(TRUE)
    {
        SingleNamedPipe = CreateNamedPipe("\\\\.\\Pipe\\calcOfComplexNumbers"
                                          , PIPE_ACCESS_DUPLEX
                                          , PIPE_TYPE_BYTE 
                                            | PIPE_READMODE_BYTE 
                                            | PIPE_WAIT
                                          , PIPE_UNLIMITED_INSTANCES
                                          , 0
                                          , 0
                                          , waitingTime
                                          , NULL
                                         );
        if(INVALID_HANDLE_VALUE == SingleNamedPipe)
        {
            cout << "Создание конвейера с ошибкой " << GetLastError();
            cout << endl;
            cin.get();
            return;
        }
        fConnected = ConnectNamedPipe(SingleNamedPipe, NULL) ? TRUE
                     : (GetLastError() == ERROR_PIPE_CONNECTED);
        if(fConnected)
        {
            cout << "Установлено новое соединение" << endl;
            hThread = (HANDLE)_beginthreadex(NULL
                                             , 0
                                             , ThreadProcedure
                                             , (void *)SingleNamedPipe
                                             , 0
                                             , NULL
                                            );
            if (0 == hThread)
            {
                cout << "_beginthreadex завершился с ошибкой ";
                cout << errno << endl;
                cin.get();
                return;
            }
            else
                CloseHandle(hThread);
        }
        else
            CloseHandle(SingleNamedPipe);
    }
    cin.get();
}
/////////////////////////////////////////////////////////////////////////////
//
//  Функция сложения 2-х комплексных чисел
//
//  FUNCTION: void AddingComplexNumbers(void)
//
//  PARAMETERS: нет
//
//  RETURN VALUE: нет
//
//  COMMENTS: FirstAddingResult  - сложение действительных частей
//                                 комплексных чисел
//            SecondAddingResult - сложение мнимых частей
//                                 комплексных чисел
//
void AddingComplexNumbers(void)
{
    float FirstAddingResult = g_ComplexNumbers[0].m_real 
                              + g_ComplexNumbers[1].m_real;
    float SecondAddingResult = g_ComplexNumbers[0].m_imaginary 
                               + g_ComplexNumbers[1].m_imaginary;
    OutputResults("Результат сложения: "
                  , FirstAddingResult
                  , SecondAddingResult
                 );
}

/////////////////////////////////////////////////////////////////////////////
//
//  Функция вычитания 2-х комплексных чисел
//
//  FUNCTION: void SubtractionComplexNumbers(void)
//
//  PARAMETERS: нет
//
//  RETURN VALUE: нет
//
//  COMMENTS: FirstSubtractionResult  - вычитание действительных частей
//                                      комплексных чисел
//            SecondSubtractionResult - вычитание мнимых частей
//                                      комплексных чисел
//
void SubtractionComplexNumbers(void)
{
    float FirstSubtractionResult = g_ComplexNumbers[0].m_real 
                                   - g_ComplexNumbers[1].m_real;
    float SecondSubtractionResult = g_ComplexNumbers[0].m_imaginary 
                                    - g_ComplexNumbers[1].m_imaginary;
    OutputResults("Результат вычитания: "
                  , FirstSubtractionResult
                  , SecondSubtractionResult
                 );
}

///////////////////////////////////////////////////////////////////////////////
//
//  Функция умножения 2-х комплексных чисел
//
//  FUNCTION: void MultipleComplexNumbers(void)
//
//  PARAMETERS: нет
//
//  RETURN VALUE: нет
//
//  COMMENTS: FirstMultipleResult  - действительная часть умножения 2-х
//                                   комплексных чисел
//            SecondMultipleResult - мнимая часть умножения 2-х
//                                   комплексных чисел
//
void MultipleComplexNumbers(void)
{
    float FirstMultipleResult = g_ComplexNumbers[0].m_real 
                                * g_ComplexNumbers[1].m_real
                                - g_ComplexNumbers[0].m_imaginary 
                                  * g_ComplexNumbers[1].m_imaginary;
    float SecondMultipleResult = g_ComplexNumbers[0].m_real 
                                 * g_ComplexNumbers[1].m_imaginary
                                 + g_ComplexNumbers[0].m_imaginary 
                                   * g_ComplexNumbers[1].m_real;
    OutputResults("Результат умножения: "
                  , FirstMultipleResult
                  , SecondMultipleResult
                 );
}

//////////////////////////////////////////////////////////////////////////////
//
//  Функция деления 2-х комплексных чисел
//
//  FUNCTION: void DivisionComplexNumbers(void)
//
//  PARAMETERS: нет
//
//  RETURN VALUE: нет
//
//  COMMENTS: FirstDivisionResult - действительная часть результата
//                                  умножения делимого на число,
//                                  являющееся сопряженным для знаменателя
//            SecondDivisionResult - мнимая часть результата
//                                   умножения делимого на число,
//                                   являющееся сопряженным для знаменателя
//            ThirdDivisionResult - результат умножения делителя
//                                  на сопряженное ему число
//
void DivisionComplexNumbers(void)
{
    float FirstDivisionResult = g_ComplexNumbers[0].m_real
                                * g_ComplexNumbers[1].m_real 
                                + g_ComplexNumbers[0].m_imaginary
                                  * g_ComplexNumbers[1].m_imaginary;
    float SecondDivisionResult = -g_ComplexNumbers[0].m_real
                                  * g_ComplexNumbers[1].m_imaginary 
                                  + g_ComplexNumbers[0].m_imaginary
                                    * g_ComplexNumbers[1].m_real;
    float ThirdDivisionResult = g_ComplexNumbers[1].m_real
                                * g_ComplexNumbers[1].m_real 
                                + g_ComplexNumbers[1].m_imaginary
                                  * g_ComplexNumbers[1].m_imaginary;
    if(ThirdDivisionResult == 0)
    {
        cout << "Division on 0. Incorrect operation!" << endl;
    }
    else
    {
        float FirstOnThirdResult = FirstDivisionResult/ThirdDivisionResult;
        float SecondOnThirdResult = SecondDivisionResult/ThirdDivisionResult;
        OutputResults("Результат деления: "
                      , FirstOnThirdResult
                      , SecondOnThirdResult
                     );
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Функция вывода результатов операции на экран
//
//  FUNCTION: void OutputResults(string, float, float)
//
//  PARAMETERS: [in] greeting      - строка приветствия
//              [in] realPart      - дейсвительная часть
//              [in] imaginaryPart - мнимая часть
//
//  RETURN VALUE: нет
//
//  COMMENTS: нет
//
void OutputResults(string greeting, float realPart, float imaginaryPart)
{
    if(imaginaryPart < 0)
    {
        cout << greeting << realPart;
        cout << imaginaryPart << COMPLEX_NUMBER_SEPARATOR << endl;
    }
    else
    {
        cout << greeting << realPart << PLUS;
        cout << imaginaryPart << COMPLEX_NUMBER_SEPARATOR << endl;
    }
}
////////////////////////////////////////////////////////////////////////////////
//
//  Процедура потока
//
//  FUNCTION: static unsigned __stdcall ThreadProcedure(LPVOID)
//
//  PARAMETERS: [in] lpvParam - фиктивный параметр потоковой функции
//
//  RETURN VALUE: TRUE - в случае корректного завершения
//
//  COMMENTS: нет
//
static unsigned __stdcall ThreadProcedure(LPVOID lpvParam)
{
    HANDLE SingleNamedPipe;
    SingleNamedPipe = (HANDLE)lpvParam;
    const int operationOfAdding = 1;
    const int operationOfSubtraction = 2;
    const int operationOfMultiple = 3;
    const int operationOfDivision = 4;
    const int clientExitCode = 109;
    while(TRUE)
    {
        DWORD bytesRead;
        if(0 >= ReadFile(SingleNamedPipe
                         , &g_ComplexNumbers
                         , sizeof(g_ComplexNumbers)
                         , &bytesRead
                         , NULL
                        )
          )
        {
            if(clientExitCode == GetLastError())
            {
                cout << "Клиент отключился " << endl;
                cin.get();
                CloseHandle(SingleNamedPipe);
            }
            else
            {
                cout << "Ошибка чтения из конвейера " << GetLastError();
                cout << endl;
                cin.get();
                CloseHandle(SingleNamedPipe);
            }
        }
        switch(g_ComplexNumbers->m_codeOfOperation)
        {
        case operationOfAdding:
            AddingComplexNumbers();
            break;
        case operationOfSubtraction:
            SubtractionComplexNumbers();
            break;
        case operationOfMultiple:
            MultipleComplexNumbers();
            break;
        case operationOfDivision:
            DivisionComplexNumbers();
            break;
        default:
            cout << "Unknown error" << endl;
        }
    }
    FlushFileBuffers(SingleNamedPipe); 
    if(0 == DisconnectNamedPipe(SingleNamedPipe))
    {
        cout << "Ошибка при разрыве соединения " << GetLastError() << endl;
        cin.get();
        CloseHandle(SingleNamedPipe);
    }
    DisconnectNamedPipe(SingleNamedPipe); 
    CloseHandle(SingleNamedPipe); 
    cout << "Клиент отключился" << endl;

    return TRUE;
}


Код клиента
Код

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <string>
#include <windows.h>
#undef max
#include <limits>

using namespace std;

#define MAX_STRUCT_SIZE             2

#define OPERATOR_ADDING             1
#define OPERATOR_SUBTRACTION        2
#define OPERATOR_MULTIPLE           3
#define OPERATOR_DIVISION           4

#define COMPLEX_NUMBER_SEPARATOR    "i"
#define PLUS                        "+"

#define  _CRT_SECURE_NO_WARNINGS 1

#define INPUT_NEW_NUMBERS           1
#define MENU_ITEM_EXIT              0

typedef struct
{
    float m_real;
    float m_imaginary;
    int m_codeOfOperation;
} TComplex;

TComplex g_ComplexNumbers[MAX_STRUCT_SIZE];

int ShowMainMenu(void);
int ShowOperationMenu(void);
void InputComplexNumbers(void);
void SendToMailpipe(HANDLE);

////////////////////////////////////////////////////////////////////////////////
//
//  Главная функция консольного приложения
//
//  FUNCTION: int main(void)
//
//  PARAMETERS: нет
//
//  RETURN VALUE: нет
//
//  COMMENTS: нет
//
void main(void)
{
    setlocale(LC_ALL, "Russian");
    int nMenu = 0;
    BOOL fSuccess;
    DWORD dwMode;
    const int AddingCode = 1;
    const int SubtractionCode = 2;
    const int MultipleCode = 3;
    const int DivisionCode =4;

    if(0 == WaitNamedPipe("\\\\.\\Pipe\\calcOfComplexNumbers"
                          , NMPWAIT_WAIT_FOREVER
                         )
      )
    {
        cout << "Ожидание соединения с ошибкой " << GetLastError() << endl;
        cin.get();
        return;
    }
    HANDLE ServerPipe;
    ServerPipe = CreateFile("\\\\.\\Pipe\\calcOfComplexNumbers"
                            , GENERIC_READ | GENERIC_WRITE
                            , 0
                            , (LPSECURITY_ATTRIBUTES)NULL
                            , OPEN_EXISTING
                            , FILE_ATTRIBUTE_NORMAL
                            , (HANDLE)NULL
                           );
    if(INVALID_HANDLE_VALUE == ServerPipe)
    {
        cout << "Создание конвейера с ошибкой " << GetLastError() << endl;
        cin.get();
        return;
    }
    cout << "Соединение установлено" << endl;
    dwMode = PIPE_READMODE_BYTE; 
    if (!(fSuccess = SetNamedPipeHandleState(ServerPipe
                                             , &dwMode
                                             , NULL
                                             , NULL
                                            )
         )
       ) 
    {
        cout << "SetNamedPipeHandleState failed with error ";
        cout << GetLastError() << endl; 
        return;
    }
    while ((nMenu = ShowMainMenu()) != MENU_ITEM_EXIT)
    {
        switch(nMenu)
        {
        case INPUT_NEW_NUMBERS:
            InputComplexNumbers();
            while ((nMenu = ShowOperationMenu()) != MENU_ITEM_EXIT)
            {
                switch (nMenu)
                {
                case OPERATOR_ADDING:
                    g_ComplexNumbers->m_codeOfOperation = AddingCode;
                    SendToMailpipe(ServerPipe);
                    break;
                case OPERATOR_SUBTRACTION:
                    g_ComplexNumbers->m_codeOfOperation = SubtractionCode;
                    SendToMailpipe(ServerPipe);
                    break;
                case OPERATOR_MULTIPLE:
                    g_ComplexNumbers->m_codeOfOperation = MultipleCode;
                    SendToMailpipe(ServerPipe);
                    break;
                case OPERATOR_DIVISION:
                    g_ComplexNumbers->m_codeOfOperation = DivisionCode;
                    SendToMailpipe(ServerPipe);
                    break;
                default:
                    cout << "Wrong menu item!" <<endl;
                }
            }
            break;
        default:
            cout << "Wrong menu item!" << endl;
        }
    }
    CloseHandle(ServerPipe);
    cin.get();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Вывод главного меню на экран
//
//  FUNCTION: int ShowMainMenu(void)
//
//  PARAMETERS: нет
//
//  RETURN VALUE: choise - выбор пользователя
//
//  COMMENTS: нет
//
int ShowMainMenu(void)
{
    cout << "\n1. ВВЕСТИ НОВЫЕ ЧИСЛА" << endl;
    cout << "---------" << endl;
    cout << "0. ВЫХОД" << endl;
    cout << "\n?>";

    int choice = 0;
    cin >> choice;
    cout << endl;
    return choice;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Вывод меню операций на экран
//
//  FUNCTION: ShowOperationMenu(int)
//
//  PARAMETERS: нет
//
//  RETURN VALUE: choiсe - выбор пользователя
//
//  COMMENTS: нет
//
int ShowOperationMenu(void)
{
    cout << "\n1. СЛОЖЕНИЕ" << endl;
    cout << "2. ВЫЧИТАНИЕ" << endl;
    cout << "3. УМНОЖЕНИЕ" << endl;
    cout << "4. ДЕЛЕНИЕ" << endl;
    cout << "---------" << endl;
    cout << "0. ВЫХОД В ГЛАВНОЕ МЕНЮ" << endl;
    cout << "\n?>";

    int choice = 0;
    cin >> choice;
    cout << endl;
    return choice;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Ввод комплексных чисел
//
//  FUNCTION: InputComplexNumbers(void)
//
//  PARAMETERS: нет
//
//  RETURN VALUE: нет
//
//  COMMENTS: BadInputRe - TRUE - действительная часть введена неверно
//                         FALSE - действительная часть введена верно
//            BadInputIm - TRUE - мнимая часть введена неверно
//                         FALSE - мнимая часть введена верно
//
void InputComplexNumbers(void)
{
    int BadInputRe, BadInputIm;
    for(int i = 0; i < MAX_STRUCT_SIZE; ++i)
    {
        cout << "Введите " << i+1 << "-е комплексное число" << endl;
        do
        {
            BadInputRe = 0;
            cout << "Real part: ";
            cin >> g_ComplexNumbers[i].m_real;
            if(!cin)
            {
                cout << "Input error" << endl;
                BadInputRe = 1;
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(),'\n');
            }
            
        }
        while(BadInputRe);
        do
        {
            BadInputIm = 0;
            cout << "Imaginary part: ";
            cin >> g_ComplexNumbers[i].m_imaginary;
            if(!cin)
            {
                cout << "Input error" << endl;
                BadInputIm = 1;
                cin.clear();
                cin.ignore(numeric_limits<streamsize>::max(),'\n');
            }
        }
        while(BadInputIm);

        cout << "Number " << i+1 << ": ";
        if(g_ComplexNumbers[i].m_imaginary < 0)
        {
            cout << g_ComplexNumbers[i].m_real;
            cout << g_ComplexNumbers[i].m_imaginary;
            cout << COMPLEX_NUMBER_SEPARATOR << endl;
        }
        else
        {
            cout << g_ComplexNumbers[i].m_real;
            cout << PLUS << g_ComplexNumbers[i].m_imaginary;
            cout << COMPLEX_NUMBER_SEPARATOR << endl;
        }
        cout << "*************\n";
    }
}

void SendToMailpipe(HANDLE ServerPipe)
{
    DWORD bytesWritten;
    if (0 == WriteFile(ServerPipe
                       , &g_ComplexNumbers
                       , sizeof(g_ComplexNumbers)
                       , &bytesWritten
                       , NULL
                      )
       )
    {
        cout << "Запись в конвейер с ошибкой " << GetLastError();
        cout << endl;
        cin.get();
        CloseHandle(ServerPipe);
        return;
    }
}

PM MAIL   Вверх
assasincore
Дата 10.5.2010, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 13.4.2010

Репутация: нет
Всего: нет



Пиши сериализатор\десириализатор. И помни про указатели, посмотри код, а точнее структуры на указатели... Массив из Указателей? А куда он указывает? Вообщем адресация....
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0814 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.