- •1. Сокеты, датаграммы и каналы связи
- •2. Инициализация приложения при работе с сокетами и завершение его работы
- •3. Создание и инициализация сокета
- •3.1. Создание сокета
- •3.2. Удаление сокета
- •3.3. Параметры сокета
- •3.4. Привязка адреса к сокету
- •3.5. Создание канала связи
- •3.5.1.Сторона сервера
- •3.5.1. Сторона клиента
- •3.5.3. Передача и прием данных
- •4. Решения при работе с сокетами
- •5. Порядок выполнения работы
- •6. Контрольные вопросы
- •Приложения
- •1. Коды ошибок различных функций при работе с сокетами
- •2. Сервер сокетов с оконным интерфейсом (протокол tcp/ip).
- •3. Клиент сокетов с оконным интерфейсом (протокол tcp/ip).
- •4. Сервер сокетов с оконным интерфейсом (протокол udp).
- •5. Клиент сокетов с оконным интерфейсом (протокол udp).
- •6. Сервер неблокирующих сокетов с использованием события wsaevent (протокол tcp/ip)
- •7. Клиент неблокирующих сокетов с использованием события wsaevent (протокол tcp/ip)
- •8. Сервер неблокирующих сокетов с использованием функции select
- •9.Клиент неблокирующих сокетов с использованием функции select
- •10. Сервер блокируюющих сокетов (протокол tcp/ip)
- •11. Клиент блокируюющих сокетов (протокол tcp/ip)
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