![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
Напишем многопоточный сервер, который ожидает соединение от клиентов, и для каждого подключенного клиента создается отдельный поток. Клиент получает с клавиатуры от пользователя строку, посылает на сервер, сервер приводит строку к верхнему регистру и посылает результат обратно клиенту.
Сервер:
#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; Прочитано: 209 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!