Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лаба14.doc
Скачиваний:
9
Добавлен:
12.11.2019
Размер:
572.93 Кб
Скачать

6. Сервер неблокирующих сокетов с использованием события wsaevent (протокол tcp/ip)

#include <stdio.h>

#include <conio.h>

#include <winsock2.h>

// порт сервера

#define SERV_PORT 5000

// струкутра для определения типа события

WSANETWORKEVENTS NetEvts;

// событие связанное с коетом

WSAEVENT hSockEvt[2];

// Сокет сервера

SOCKET srv_socket;

SOCKET clients[10];

int CltSockCnt=0;

// Длина использованного сокета

int acc_sin_len;

// Адрес использованного сокета

SOCKADDR_IN acc_sin;

// Локальный сокет

SOCKADDR_IN local_sin;

int main ()

{

int rc;

WSADATA WSAData;

char szTemp[128];

// Инициализация и проверка версии Windows Sockets

rc = WSAStartup(MAKEWORD(1, 1), &WSAData);

if(rc != 0)

{

printf("\nWSAStartup Error\n");

getch();

return FALSE;

}

// Отображаем описание и версию системы Windows Sockets

printf("\nServer initialization...\n");

wsprintf(szTemp, "Server use %s %s",

WSAData.szDescription,WSAData.szSystemStatus);

printf("%s\n",szTemp);

struct sockaddr_in srv_address;

for(int k=0; k < 10; k++ )

hSockEvt[k] = WSACreateEvent();

// hSockEvt[1] = WSACreateEvent();

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

srv_socket = socket(AF_INET, SOCK_STREAM, 0);

if(srv_socket == INVALID_SOCKET)

{

printf("\nsocket Error \n");

getch();

return;

}

printf("\nSocket is created.\n");

// Устанавливаем адрес IP и номер порта

srv_address.sin_family = AF_INET;

srv_address.sin_addr.s_addr = INADDR_ANY;

srv_address.sin_port = htons(SERV_PORT);

// Связываем адрес IP с сокетом

if(bind(srv_socket, (LPSOCKADDR)&srv_address,

sizeof(srv_address)) == SOCKET_ERROR)

{

// При ошибке закрываем сокет

closesocket(srv_socket);

printf("\nbind Error.\n");

getch();

return;

}

printf("\nSocket is binded.\n");

// устанавливаем событие связанное с сокетом и сообщения о которых оно сигнализирует

WSAEventSelect(srv_socket, hSockEvt[0],FD_READ|FD_ACCEPT|FD_CLOSE);

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

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

if(listen(srv_socket, 1) == SOCKET_ERROR)

{

closesocket(srv_socket);

printf("\nlisten Error\n");

getch();

return;

}

printf("\nSocket in listen mode.\n");

clients[CltSockCnt] = srv_socket;

CltSockCnt++;

while (1)

{

// ожидание событий от сокетов

WSAWaitForMultipleEvents(1,hSockEvt,FALSE,WSA_INFINITE,FALSE);

// цикл проверки клиентов

for(int i=0; i<CltSockCnt;i++)

{

// определяем какое событие произошло

WSAEnumNetworkEvents(clients[i],NULL,&NetEvts);

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

if (NetEvts.lNetworkEvents & FD_ACCEPT)

{

// Определяем размер адреса сокета

acc_sin_len = sizeof(acc_sin);

// Разрешаем установку соединения

clients[CltSockCnt] = accept(srv_socket, (LPSOCKADDR)&acc_sin,

(int FAR *)&acc_sin_len);

if(srv_socket == INVALID_SOCKET)

{

printf("\n accept Error, invalid socket\n");

getch();

return;

}

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

WSAEventSelect( clients[CltSockCnt],

hSockEvt[CltSockCnt],FD_READ|FD_ACCEPT|FD_CLOSE);

CltSockCnt++;

printf("\nConnection accepted.\n");

}

// сообщение о том, что можно читать данные из сокета

// (пришло сообщение от клиента)

if (NetEvts.lNetworkEvents & FD_READ )

{

rc = recv((SOCKET)clients[i], szTemp, 256, 0);

if(rc)

{

szTemp[rc] = '\0';

}

printf("\nMessage from client %d: %s\n",i,szTemp);

// Посылаем сообщение

char szBuf[100];

lstrcpy(szBuf,"test");

send(clients[i], szBuf, lstrlen(szBuf), 0);

printf("\nMessage sent to Client %d.\n", i);

}

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

if (NetEvts.lNetworkEvents & FD_CLOSE )

{

printf("\nClient %d close session\n", i);

closesocket(clients[i]);

for(int j=i; j<CltSockCnt;j++ )

{

clients[j] = clients[j+1];

}

CltSockCnt--; //rpc

}

NetEvts.lNetworkEvents =0;

}

}

// Если сокет был создан, закрываем его

if(srv_socket != INVALID_SOCKET)

{

closesocket(srv_socket);

}

}

Приложение 7

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]