- •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)
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,¤t,NULL,NULL,NULL);
// если установлен сокет, который был на прослушивании
if (FD_ISSET(srv_socket,¤t))
{
// Определяем размер адреса сокета
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],¤t))
{
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