| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Сервер-клиент.отправка сообщений |
| Автор: weirdo 21.10.2007, 14:38 |
| Даны два процесса-клиент и сервер...среда разработки VS 6.0 . Должны передаваться сообщения как от клиетну серверу так и обратно...тут ошибка...не могу найти...помогите плиз.То есть серверу,например, сообщение пишу..и оно уходит в никуда...до клиента не доходит и наоборот...а должно отображаться. Сервер: #include <conio.h> #include <stdio.h> #include <windows.h> #define BUFFER_SIZE 1024 //1k void quit(HANDLE hNamedPipe) { CloseHandle(hNamedPipe); printf("\nProcess zavershen..."); } int main() { HANDLE hNamedPipe; // Идентификатор канала Pipe LPSTR lpszPipeName = "\\\\.\\pipe\\$MyPipe$"; // Имя создаваемого канала Pipe BOOL fConnected; // Флаг успешного создания канала DWORD cbRead; // Количество байт данных, принятых через канал DWORD cbWritten; // Количество байт данных, переданных через канал // Создаем канал Pipe, имеющий имя lpszPipeName hNamedPipe = CreateNamedPipe( lpszPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 512, 512, 5000, NULL); // Проверка создания канала if(hNamedPipe == INVALID_HANDLE_VALUE) { printf("CreateNamedPipe: Oshibka "); printf("%ld\n", GetLastError()); quit(hNamedPipe); getch(); return 0; } // Ожидаем соединения со стороны клиента fConnected = ConnectNamedPipe(hNamedPipe, NULL); // При возникновении ошибки выводим ее код if(!fConnected) { switch(GetLastError()) { case ERROR_NO_DATA: printf("ConnectNamedPipe: ERROR_NO_DATA"); quit(hNamedPipe); getch(); return 0; case ERROR_PIPE_CONNECTED: printf("ConnectNamedPipe: ERROR_PIPE_CONNECTED"); quit(hNamedPipe); getch(); return 0; case ERROR_PIPE_LISTENING: printf("ConnectNamedPipe: ERROR_PIPE_LISTENING"); quit(hNamedPipe); getch(); return 0; case ERROR_CALL_NOT_IMPLEMENTED: printf("ConnectNamedPipe: ERROR_CALL_NOT_IMPLEMENTED"); quit(hNamedPipe); getch(); return 0; default: printf("ConnectNamedPipe: Ошибка "); printf("%ld\n", GetLastError()); quit(hNamedPipe); getch(); return 0; } quit(hNamedPipe); getch(); return 0; } // Выводим сообщение об успешном создании канала printf("Connected...\n"); char WMess[BUFFER_SIZE]; // написанное сообщение char RMess[BUFFER_SIZE]; // полученное сообщение gets(WMess); if (!WriteFile(hNamedPipe, WMess, sizeof(WMess), &cbWritten, NULL)) { quit(hNamedPipe); getch(); return 0; } if(ReadFile(hNamedPipe, RMess, sizeof(RMess), &cbRead, NULL)) printf("\n Sent message: %ch", RMess); else { printf("ReadFile: Oshibka "); printf("%ld\n", GetLastError()); quit(hNamedPipe); getch(); return 0; } printf("\n"); quit(hNamedPipe); getch(); return 0; } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Клиент: #include <conio.h> #include <stdio.h> #include <windows.h> #define BUFFER_SIZE 1024 //1k void error(HANDLE hNamedPipe) { printf("%ld\n", GetLastError()); CloseHandle(hNamedPipe); printf("\nПроцесс завершен. Нажмите любую клавишу..."); } int main() { char szPipeName[256]; // Буфер для имени канала Pipe HANDLE hNamedPipe; // Идентификатор канала Pipe DWORD cbWritten; // Количество байт, переданных через канал DWORD cbRead; // Количество байт, принятых через канал char WMess[BUFFER_SIZE]; // написанное сообщение char RMess[BUFFER_SIZE]; // полученное сообщение strcpy(szPipeName, "\\\\.\\pipe\\$MyPipe$"); // Создаем канал с процессом PIPES hNamedPipe = CreateFile(szPipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // Если возникла ошибка, выводим ее код и завершаем работу приложения if(hNamedPipe == INVALID_HANDLE_VALUE) { printf("CreateFile: Ошибка "); error(hNamedPipe); getch(); return 0; } // Выводим сообщение о создании канала printf("Соединение установлено...\n"); gets(WMess); if (!WriteFile(hNamedPipe, WMess, sizeof(WMess), &cbWritten, NULL)) { ///вот тута вопрос...если на сервере отправленное сообщение было WMess...то тут будет наоборот?? error(hNamedPipe); getch(); return 0; } if(ReadFile(hNamedPipe, RMess, sizeof(RMess), &cbRead, NULL)) printf("\n Sent message: %ch", RMess); else { printf("ReadFile: Ошибка "); printf("%ld\n", GetLastError()); error(hNamedPipe); getch(); return 0; } printf("\n"); CloseHandle(hNamedPipe); printf("\nПроцесс завершен. Нажмите любую клавишу..."); getch(); return 0; } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| Автор: EnergoHokum 24.10.2007, 14:59 |
| Первое, что бросается в глаза - у тебя и на клиенте и на сервере одновременно идут запись, потом так же чтение. Разверни у кого-нить, чтобы получилось сервер->запись && клиент->чтение ___ сервер->чтение && клиент->запись. А вообще (IMHO) лучше создать два pipe - один для записи, второй для чтения. Так не будет конфликтов. |
| Автор: weirdo 24.10.2007, 18:34 |
| Я могу вообще использовать универсальную функцию как в сервере так и в клиенте CallNamedPipe: BOOL CallNamedPipe( LPCTSTR lpNamedPipeName, // адрес имени канала LPVOID lpOutBuffer, // адрес буфера для записи DWORD nOutBufferSize, // размер буфера для записи LPVOID lpInBuffer, // адрес буфера для чтения DWORD nInBufferSize, // размер буфера для чтения LPDWORD lpBytesRead, // адрес переменной для записи // количества прочитанных байт данных DWORD nTimeOut); // время ожидания в миллисекундах НО!!!! я не знаю что вписать в lpOutBuffer и lpInBuffer и lpBytesRead....может сталкивался с таким??? |
| Автор: EnergoHokum 25.10.2007, 07:28 |
| Так, значитЪ, из MSDN: CallNamedPipe выполняет соединение на named pipe (и ожидаает её instance, не знаю, как это корректно перевести), выполняет запись/чтение и закрывает эту pipe. Т. е. эту функцию ты можешь использовать только с одной стороны, т. к. установить, что сначала нужно делать (читать или писать) для неё невозможно. Дальше: lpInBuffer - указатель на буфер приёма, lpOutBuffer - указатель на буфер передачи, lpBytesRead - указатель на переменную, в которую пишется количество принятых байтов (char-ов). |