Новичок
Профиль
Группа: Участник
Сообщений: 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; } }
|
|