Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Учебный проект



Напишем многопоточный сервер, который ожидает соединение от клиентов, и для каждого подключенного клиента создается отдельный поток. Клиент получает с клавиатуры от пользователя строку, посылает на сервер, сервер приводит строку к верхнему регистру и посылает результат обратно клиенту.

Сервер:

#include <windows.h>

#include <process.h>

#include <stdio.h>

#define BUFSIZE 4096

DWORD WINAPI thread_proc(LPVOID);

VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);

int main(VOID)

{

BOOL fConnected;

HANDLE hPipe, hThread;

char *pipename = "\\\\.\\pipe\\mynamedpipe";

// Мы в цикле создаем экземпляр канал и ожидаем подключение клиента.

// Когда клиент подключится, мы создает отдельный поток для работы с ним.

printf("Server is ready\n");

while (TRUE) {

hPipe = CreateNamedPipe(

pipename, // имя канала

PIPE_ACCESS_DUPLEX, // дуплексный режим

PIPE_TYPE_MESSAGE | // запись в виде сообщений

PIPE_READMODE_MESSAGE | // чтение в виде сообщений

PIPE_WAIT, // блокирующий режим

PIPE_UNLIMITED_INSTANCES, // максимальное число экземпляров

BUFSIZE, // размер выходного буфера

BUFSIZE, // размер входного буфера

0, // тайм-аут

NULL); // атрибуты безопасности

if (hPipe == INVALID_HANDLE_VALUE) {

printf("CreatePipe failed with error 0x%08X\n", GetLastError());

return 0;

}

// Ждем подключения клиента

fConnected = ConnectNamedPipe(hPipe, NULL)? TRUE

: (GetLastError() == ERROR_PIPE_CONNECTED);

if (fConnected) {

printf("Got a new connection.\n");

// Создаем поток для клиента

if (NULL == (hThread = (HANDLE)_beginthreadex(NULL, 0, thread_proc, (void*)hPipe, 0, NULL))) {

printf("_beginthreadex failed with error %d\n", errno);

return 0;

}

else

CloseHandle(hThread);

} else

// Клиент не может подключиться, закрываем канал

CloseHandle(hPipe);

}

return 0;

}

DWORD WINAPI thread_proc(LPVOID lpvParam)

{

char chRequest[BUFSIZE];

char chReply[BUFSIZE];

DWORD cbBytesRead, cbReplyBytes, cbWritten;

BOOL fSuccess;

HANDLE hPipe;

hPipe = (HANDLE) lpvParam;

while (TRUE)

{

// Читаем запрос от клиента

fSuccess = ReadFile(

hPipe,

chRequest, // буфер для данных

sizeof(chRequest), // размер буфера

&cbBytesRead, // число прочитанных байт

NULL);

if (! fSuccess || cbBytesRead == 0)

break;

// Приведем полученную строку к верхнему регистру

for (cbReplyBytes = 0; (cbReplyBytes < BUFSIZE - 1) && (chRequest[cbReplyBytes]!= 0); cbReplyBytes++)

chReply[cbReplyBytes] = toupper(chRequest[cbReplyBytes]);

chReply[cbReplyBytes++] = '\0';

// Пишем ответ в канал

fSuccess = WriteFile(

hPipe,

chReply, // откуда писать

cbReplyBytes, // сколько писать

&cbWritten, // число записанных байт

NULL);

if (! fSuccess || cbReplyBytes!= cbWritten)

break;

}

// Вполним принудительный сброс буферов на сторону клиента

FlushFileBuffers(hPipe);

DisconnectNamedPipe(hPipe);

CloseHandle(hPipe);

printf("Client terminated\n");

return 1;

}

Клиент:

#define _CRT_SECURE_NO_WARNINGS 1

#include <windows.h>

#include <stdio.h>

#include <conio.h>

#define BUFSIZE 512

int main(void)

{

char *pipename = "\\\\.\\pipe\\mynamedpipe";

HANDLE hPipe;

char inputBuffer[BUFSIZE];

char chBuf[BUFSIZE];

BOOL fSuccess;

DWORD cbRead, cbWritten, dwMode;

char ch;

// Пробуем открыть именованный канал; ждем экземпляр канал, если необходимо

while (TRUE) {

if (INVALID_HANDLE_VALUE!= (hPipe = CreateFile(pipename,

GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)))

break;

// ERROR_PIPE_BUSY - это не ошибка

if (ERROR_PIPE_BUSY!= GetLastError()) {

printf("Could not open pipe. Error 0x%08X\n", GetLastError());

return 0;

}

// Все экземпяры канала заняты, ждем

if (!WaitNamedPipe(pipename, NMPWAIT_WAIT_FOREVER)) {

printf("Could not open pipe.");

return 0;

}

}

printf("Connected to server\n");

// Мы подключились к каналу. Переведем его в режим чтения сообщений

dwMode = PIPE_READMODE_MESSAGE;

if (!(fSuccess = SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL))) {

printf("SetNamedPipeHandleState failed with error 0x%08X\n", GetLastError());

return 0;

}

do {

printf("Enter a string: ");

scanf("%s", inputBuffer);

// Шлем сообщение

if (!(fSuccess = WriteFile(

hPipe,

inputBuffer, // буфер сообщения

strlen(inputBuffer)+1, // размер сообщения (+1 - закрывающий ноль в строке)

&cbWritten, // число фактически переданных байт

NULL)))

{

printf("WriteFile failed with error 0x%08X\n", GetLastError());

return 0;

}

if (!(fSuccess = ReadFile(

hPipe,

chBuf, // буфер куда поместить ответ

BUFSIZE, // размер буфера

&cbRead, // число фактически прочитанных байт

NULL)))

{

if (GetLastError()!= ERROR_MORE_DATA) {

printf("ReadFile failed with error 0x%08X\n", GetLastError());

break;

} else {

// сервер посылает нам больше данных, чем мы расчитывали....

// это нужно как-то обработать......

abort(); // создаем ошибку, пока не придумали как обрабатывать

}

}

printf("Reply from server: %s\n", chBuf);

printf("\n\nTry again (Y/N)? ");

ch = _getch();

printf("%c\n", ch);

} while ('N'!= toupper(ch));

CloseHandle(hPipe);

return 0;

}





Дата публикования: 2015-10-09; Прочитано: 199 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.012 с)...