|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Сервер
Тексти програм.
#include "stdafx.h" #include <stdio.h> #include <winsock2.h> #include <windows.h>
#define MY_PORT 666 // Порт, который слушает сервер
// прототип функции, обслуживающий // подключившихся пользователей DWORD WINAPI ToClient(LPVOID client_socket);
// глобальная переменная – количество // активных пользователей int nclients = 0;
int main(int argc, char* argv[]) { char buff[1024]; // Буфер для различных нужд
printf("LAN TEST SERVER\n");
// Инициализация Библиотеки Сокетов // Т.к. возвращенная функцией информация // не используется ей передается указатель на // рабочий буфер, преобразуемый // к указателю на структуру WSADATA. // // буфер должен быть не менее // полкилобайта размером (структура WSADATA // занимает 400 байт) if (WSAStartup(0x0202,(WSADATA *) &buff[0])) { // Ошибка! printf("Error WSAStartup %d\n", WSAGetLastError()); return -1; }
// создание сокета SOCKET mysocket; // 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; }
// связывание сокета с локальным адресом sockaddr_in local_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; }
// ожидание подключений // размер очереди – 0x100 if (listen(mysocket, 0x100)) { // Ошибка printf("Error listen %d\n",WSAGetLastError()); closesocket(mysocket); WSACleanup(); return -1; }
printf("Waiting for connections\n");
// извлекаем сообщение из очереди SOCKET client_socket; // сокет для клиента sockaddr_in client_addr; // адрес клиента // (заполняется системой)
// функции accept необходимо передать размер // структуры int client_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 connection!\n", (hst)?hst->h_name:"", inet_ntoa(client_addr.sin_addr));
// Вызов нового потока для обслужвания клиента // Да, для этого рекомендуется использовать // _beginthreadex но, поскольку никаких вызов // функций стандартной Си библиотеки поток не // делает, можно обойтись и CreateThread DWORD thID; CreateThread(NULL,NULL,ToClient, &client_socket,NULL,&thID); } return 0; }
// Эта функция создается в отдельном потоке и // обсуживает очередного подключившегося клиента // независимо от остальных DWORD WINAPI ToClient(LPVOID client_socket) { SOCKET my_sock; my_sock=((SOCKET *) client_socket)[0]; char buff[20*1024];
// цикл эхо-сервера: прием строки от клиента и // возвращение ее клиенту int bytes_recv; while((bytes_recv=recv(my_sock,&buff[0],sizeof(buff),0))&& bytes_recv!=SOCKET_ERROR){ send(my_sock,&buff[0],bytes_recv,0); printf("Data resived. \n"); }
// если мы здесь, то произошел выход из цикла по // причине возращения функцией recv ошибки – // соединение клиентом разорвано nclients--; // уменьшаем счетчик активных клиентов printf("-disconnect\n\n");
// закрываем сокет closesocket(my_sock); return 0; }
Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.01 сек.) |