Книга: Системное программирование в среде Windows

Пример: клиент на основе сокета

Пример: клиент на основе сокета

Программа 12.1 представляет собой переработанный вариант клиентской программы clientNP (программа 11.2), которая использовалась в случае именованных каналов. Преобразование программы осуществляется самым непосредственным образом и требует лишь некоторых пояснений.

• Вместо обнаружения сервера с помощью почтовых ящиков пользователь вводит IP-адрес сервера в командной строке. Если IP-адрес не указан, используется заданный по умолчанию адрес 127.0.0.1, соответствующий локальной системе.

• Для отправки и приема сообщений применяются функции, например, ReceiveMessage, которые здесь не представлены.

• Номер порта, SERVER_PORT, определен в заголовочном файле ClntSrvr.h.

Хотя код написан для выполнения под управлением Windows, единственная зависимость от Windows связана с использованием вызовов функций, имеющих префикс WSA.

Программа 12.1. clientSK: клиент на основе сокетов 

/* Глава 12. clientSK.с */
/* Однопоточный клиент командной строки. */
/* ВЕРСИЯ НА ОСНОВЕ WINDOWS SOCKETS. */
/* Считывает последовательность команд для пересылки серверному процессу*/
/* через соединение с сокетом. Дожидается ответа и отображает его. */
#define _NOEXCLUSIONS /* Требуется для включения определений сокета. */
#include "EvryThng.h"
#include "ClntSrvr.h" /* Определяет структуры записей запроса и ответа. */
/* Функции сообщения для обслуживания запросов и ответов. */
/* Кроме того, ReceiveResponseMessage отображает полученные сообщения. */
static DWORD SendRequestMessage(REQUEST *, SOCKET);
static DWORD ReceiveResponseMessage(RESPONSE *, SOCKET);
struct sockaddr_in ClientSAddr; /* Адрес сокета клиента. */
int _tmain(DWORD argc, LPTSTR argv[]) {
 SOCKET ClientSock = INVALID_SOCKET;
 REQUEST Request; /* См. ClntSrvr.h. */
 RESPONSE Response; /* См. ClntSrvr.h. */
 WSADATA WSStartData; /* Структура данных библиотеки сокета. */
 BOOL Quit = FALSE;
 DWORD ConVal, j;
 TCHAR PromptMsg[] = _T("nВведите команду> ");
 TCHAR Req[MAX_RQRS_LEN];
 TCHAR QuitMsg[] = _T("$Quit");
 /* Запрос: завершить работу клиента. */
 TCHAR ShutMsg[] = _T("$ShutDownServer"); /* Остановить все потоки. */
 CHAR DefaultIPAddr[] = "127.0.0.1"; /* Локальная система. */
 /* Инициализировать библиотеку WSA; задана версия 2.0, но будет работать и версия 1.1. */
 WSAStartup(MAKEWORD(2, 0), &WSStartData);
 /* Подключиться к серверу. */
 /* Следовать стандартной процедуре вызова последовательности функций socket/connect клиентом. */
 ClientSock = socket(AF_INET, SOCK_STREAM, 0);
 memset(&ClientSAddr, 0, sizeof(ClientSAddr));
 ClientSAddr.sin_family = AF_INET;
 if (argc >= 2) ClientSAddr.sin_addr.s_addr = inet_addr(argv [1]);
 else ClientSAddr.sin_addr.s_addr = inet_addr(DefaultIPAddr);
 ClientSAddr.sin_port = htons(SERVER_PORT);
 /* Номер порта определен равным 1070. */
 connect(ClientSock, (struct sockaddr *)&ClientSAddr, sizeof(ClientSAddr));
 /* Основной цикл для вывода приглашения на ввод команд, посылки запроса и получения ответа. */
 while (!Quit) {
  _tprintf(_T("%s"), PromptMsg);
  /* Ввод в формате обобщенных строк, но команда серверу должна указываться в формате ASCII. */
  _fgetts(Req, MAX_RQRS_LEN-1, stdin); 
  for (j = 0; j <= _tcslen(Req) Request.Record[j] = Req[j];
  /* Избавиться от символа новой строки в конце строки. */
  Request.Record[strlen(Request.Record) – 1] = '';
  if (strcmp(Request.Record, QuitMsg) == 0 || strcmp(Request.Record, ShutMsg) == 0) Quit = TRUE;
  SendRequestMessage(&Request, ClientSock);
  ReceiveResponseMessage(&Response, ClientSock);
 }
 shutdown(ClientSock, 2); /* Запретить посылку и прием сообщений. */
 closesocket(ClientSock);
 WSACleanup();
 _tprintf(_T("n****Выход из клиентской программыn"));
 return 0;
}
 

Оглавление книги


Генерация: 1.152. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз