Пример сервера для программы обмена сообщениями между клиентами и сервером



 

#include<stdio.h>

#include<winsock2.h>// Wincosk2.h долженбыть

// подключенраньшеwindows.h!

#include<windows.h>

 

#defineMY_PORT 666

// Порт, который слушает сервер

 

// макрос для печати количества активных

// пользователей

#definePRINTNUSERSif (nclients)\

printf("%d user on-line\n",nclients);\

elseprintf("No User on line\n");

 

// прототипфункции, обслуживающий

// подключившихсяпользователей

DWORDWINAPISexToClient(LPVOIDclient_socket);

 

// глобальная переменная – количество

// активных пользователей

intnclients = 0;

 

int main(intargc, char* argv[])

{

       charbuff[1024]; // Буфер для различных нужд

 

       printf("TCP SERVER DEMO\n");

 

       // Шаг 1 - Инициализация Библиотеки Сокетов

       // Т.к. возвращенная функцией информация

       // не используется ей передается указатель на

       // рабочий буфер, преобразуемый

       // к указателю на структуру WSADATA.

       // Такой прием позволяет сэкономить одну

       // переменную, однако, буфер должен быть не менее

       // полкилобайта размером (структура WSADATA

       // занимает 400 байт)

       if (WSAStartup(0x0202, (WSADATA *)&buff[0]))

       {

                   // Ошибка!

                   printf("Error WSAStartup %d\n",

                              WSAGetLastError());

                   return -1;

       }

 

       // Шаг 2 - созданиесокета

       SOCKETmysocket;

       // AF_INET - сокет Интернета

       // SOCK_STREAM - потоковый сокет (с

       // установкой соединения)

       // 0 - по умолчанию выбирается TCP протокол

       if ((mysocket = socket(AF_INET, SOCK_STREAM, 0))<0)

       {

                   // Ошибка!

                   printf("Error socket %d\n", WSAGetLastError());

                   WSACleanup();

                   // Деиницилизациябиблиотеки Winsock

                   return -1;

       }

 

       // Шаг 3 связывание сокета с локальным адресом

       sockaddr_inlocal_addr;

       local_addr.sin_family = AF_INET;

       local_addr.sin_port = htons(MY_PORT);

       // не забываем о сетевом порядке!!!

       local_addr.sin_addr.s_addr = 0;

       // сервер принимает подключения

       // на все IP-адреса

 

       // вызываем bind длясвязывания

       if (bind(mysocket, (sockaddr *)&local_addr,

                   sizeof(local_addr)))

       {

                   // Ошибка

                   printf("Error bind %d\n", WSAGetLastError());

                   closesocket(mysocket); // закрываемсокет!

                   WSACleanup();

                   return -1;

       }

 

       // Шаг 4 ожидание подключений

       // размер очереди – 0x100

       if (listen(mysocket, 0x100))

       {

                   // Ошибка

                   printf("Error listen %d\n", WSAGetLastError());

                   closesocket(mysocket);

                   WSACleanup();

                   return -1;

       }

 

       printf("Waiting for client\n");

 

       // Шаг 5 извлекаем сообщение из очереди

       SOCKETclient_socket; // сокет для клиента

       sockaddr_inclient_addr; // адресклиента

                                                                                         // (заполняется системой)

 

                                                                                         // функции accept необходимо передать размер

                                                                                         // структуры

       intclient_addr_size = sizeof(client_addr);

 

       // цикл извлечения запросов на подключение из

       // очереди

       while ((client_socket = accept(mysocket, (sockaddr *)

                   &client_addr, &client_addr_size)))

       {

                   nclients++; // увеличиваем счетчик

                                                                  // подключившихся клиентов

 

                                                                  // пытаемся получить имя хоста

                   HOSTENT *hst;

                   hst = gethostbyaddr((char *)

                              &client_addr.sin_addr.s_addr, 4, AF_INET);

 

                   // выводсведенийоклиенте

                   printf("+%s [%s] new connect!\n",

                              (hst) ? hst->h_name : "",

                              inet_ntoa(client_addr.sin_addr));

                   PRINTNUSERS

 

                              // Вызов нового потока для обслуживания клиента

                              // Да, для этого рекомендуется использовать

                              // _beginthreadex но, поскольку никаких вызов

                              // функций стандартной Си библиотеки поток не

                              // делает, можно обойтись и CreateThread

                              DWORDthID;

                   CreateThread(NULL, NULL, SexToClient,

                              &client_socket, NULL, &thID);

       }

       return 0;

}

 

// Эта функция создается в отдельном потоке и

// обсуживает очередного подключившегося клиента

// независимо от остальных

DWORDWINAPISexToClient(LPVOIDclient_socket)

{

       SOCKETmy_sock;

       my_sock = ((SOCKET *)client_socket)[0];

       char buff[20 * 1024];

#definesHELLO"Hello, Sailor\r\n"

 

       // отправляем клиенту приветствие

       send(my_sock, sHELLO, sizeof(sHELLO), 0);

 

       // цикл эхо-сервера: прием строки от клиента и

       // возвращение ее клиенту

       intbytes_recv;

       while ((bytes_recv =

                   recv(my_sock, &buff[0], sizeof(buff), 0))

                   &&bytes_recv != SOCKET_ERROR)

       {

                   printf("%s", buff);

                   send(my_sock, &buff[0], bytes_recv, 0);

       }

 

       // если мы здесь, то произошел выход из цикла по

       // причине возращения функцией recv ошибки –

       // соединение клиентом разорвано

       nclients--; // уменьшаем счетчик активных клиентов

       printf("-disconnect\n"); PRINTNUSERS

 

                   // закрываемсокет

                   closesocket(my_sock);

       return 0;

}

 

Примерклиента:

// Пример простого TCP клиента

#include<stdio.h>

#include<string.h>

#include<winsock2.h>

#include<windows.h>

 

 

#definePORT 666

#defineSERVERADDR"127.0.0.1"

 

int main(intargc, char* argv[])

{

       char buff[1024];

       printf("TCP DEMO CLIENT\n");

 

       // Шаг 1 - инициализациябиблиотеки Winsock

       if (WSAStartup(0x202, (WSADATA *)&buff[0]))

       {

                   printf("WSAStart error %d\n", WSAGetLastError());

                   return -1;

       }

 

       // Шаг 2 - созданиесокета

       SOCKETmy_sock;

       my_sock = socket(AF_INET, SOCK_STREAM, 0);

       if (my_sock< 0)

       {

                   printf("Socket() error %d\n", WSAGetLastError());

                   return -1;

       }

 

       // Шаг 3 - установка соединения

 

       // заполнение структуры sockaddr_in

       // указание адреса и порта сервера

       sockaddr_indest_addr;

       dest_addr.sin_family = AF_INET;

       dest_addr.sin_port = htons(PORT);

       HOSTENT *hst;

 

       // преобразование IP адреса из символьного в

       // сетевойформат

       if (inet_addr(SERVERADDR) != INADDR_NONE)

                   dest_addr.sin_addr.s_addr = inet_addr(SERVERADDR);

       else

                   // попытка получить IP адрес по доменному

                   // имени сервера

                   if (hst = gethostbyname(SERVERADDR))

                              // hst->h_addr_list содержит не массив адресов,

                              // а массив указателей на адреса

                              ((unsignedlong *)&dest_addr.sin_addr)[0] =

                              ((unsignedlong **)hst->h_addr_list)[0][0];

                   else

                   {

                              printf("Invalid address %s\n", SERVERADDR);

                              closesocket(my_sock);

                              WSACleanup();

                              return -1;

                   }

 

       // адрес сервера получен – пытаемся установить

       // соединение

       if (connect(my_sock, (sockaddr *)&dest_addr,

                   sizeof(dest_addr)))

       {

                   printf("Connect error %d\n", WSAGetLastError());

                   return -1;

       }

 

       printf("Соединение с %s успешно установлено\n\

Type quit for quit\n\n", SERVERADDR);

 

       // Шаг 4 - чтение и передача сообщений

       intnsize;

       while ((nsize = recv(my_sock, &buff[0],

                   sizeof(buff) - 1, 0))

                   !=SOCKET_ERROR)

       {

                   // ставим завершающий ноль в конце строки

                   buff[nsize] = 0;

 

                   // выводимнаэкран

                   printf("S=>C:%s", buff);

 

                   // читаем пользовательский ввод с клавиатуры

                   printf("S<=C:"); fgets(&buff[0], sizeof(buff) - 1,

                              stdin);

 

                   // проверкана "quit"

                   if (!strcmp(&buff[0], "quit\n"))

                   {

                              // Корректный выход

                              printf("Exit...");

                              closesocket(my_sock);

                              WSACleanup();

                              return 0;

                   }

 

                   // передаем строку клиента серверу

                   send(my_sock, &buff[0], nsize, 0);

       }

 

       printf("Recv error %d\n", WSAGetLastError());

       closesocket(my_sock);

       WSACleanup();

       return -1;

}

 

 


Дата добавления: 2018-05-13; просмотров: 202; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!