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

8. Сервер неблокирующих сокетов с использованием функции select

#include <windows.h>

#include <stdio.h>

#include <conio.h>

#include <winsock.h>

#define SERV_PORT 5000

// множества содержащие информацию о сокетах

fd_set master;

fd_set current;

SOCKET clients[100];

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

SOCKET srv_socket;

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

int acc_sin_len;

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

SOCKADDR_IN acc_sin;

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

SOCKADDR_IN local_sin;

//struct sockaddr SAdr;

int main ()

{

int rc;

int iClCnt=0;

WSADATA WSAData;

char szTemp[128];

//select

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

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

if(rc != 0)

{

//MessageBox(NULL, "WSAStartup Error", "Error", MB_OK);

printf("\nWSAStartup Error\n");

getch();

return FALSE;

}

FD_ZERO(&master);

// Отображаем описание и версию системы 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;

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

srv_socket = socket(AF_INET, SOCK_STREAM, 0);

if(srv_socket == INVALID_SOCKET)

{

//MessageBox(NULL, "socket Error", "Error", MB_OK);

printf("\nsocket Error \n");

getch();

return;

}

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

// устранение ошибки при повторном запуске сервера

char yes = 1 ;

if (setsockopt(srv_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)

{

perror("setsockopt");

exit(1);

}

// Устанавливаем адрес 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");

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

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

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

{

closesocket(srv_socket);

printf("\nlisten Error\n");

getch();

return;

}

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

// добавление сокета к множеству

FD_SET(srv_socket,&master);

while (1)

{

current = master;

// установка (помечание) соответстующих сокетов в множестве

select(0,&current,NULL,NULL,NULL);

// если установлен сокет, который был на прослушивании

if (FD_ISSET(srv_socket,&current))

{

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

acc_sin_len = sizeof(acc_sin);

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

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

(int FAR *)&acc_sin_len);

if(clients[iClCnt] == INVALID_SOCKET)

{

// "Error", MB_OK);

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

getch();

return;

}

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

FD_SET(clients[iClCnt],&master);

iClCnt++;

}

// есть ифнормация для чтения от клиента

for (int j=0; j < iClCnt; j++ )

{

if (FD_ISSET(clients[j],&current))

{

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

if(rc > 0)

{

szTemp[rc] = '\0';

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

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

char szBuf[100];

lstrcpy(szBuf,"test");

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

printf("\nMessage sent.\n");

// printf("\nPress any key to close socket.\n");

}

else

{

iClCnt--;

for (int k = j; k < iClCnt; k++)

clients[k] = clients[k+1];

closesocket(clients[j]);

FD_CLR(clients[j],&master);

}

}

}

}

getch();

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

if(srv_socket != INVALID_SOCKET)

{

closesocket(srv_socket);

}

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

{

closesocket(clients[k]);

}

}

Приложение 9

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