Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯСтр 1 из 3Следующая ⇒
Методические указания для выполнения лабораторной работы № 7 По курсу «Операционные системы и системное программирование»
«Сетевое программирование в Windows»
Полоцк, 2017 ЦЕЛЬ РАБОТЫ Создание распределенных сетевых приложений. КРАТКИЕ ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ Cокеты(sockets) представляют собой высокоуровневый унифицированный интерфейс взаимодействия с телекоммуникационными протоколами. Свой первый цикл статей я посвящу только одной реализации сокетов - Winsock2. Библиотека Winsock поддерживает два вида сокетов синхронные и асинхронные. Синхронные сокеты задерживают управление на время выполнения операции, а Асинхронные - возвращают его немедленно, продолжая работать в фоновом режиме. Сокеты, независимо от вида, деляться на три типа: потоковые, сырые(windows их не "держит") и дейтаграммные. Потоковые сокеты работают с установкой соединения, обеспечивая надежную идентификацию обеих сторон и гарантируют целостность и успешность доставки данных,опираються на протокол TCP. Дейтаграммные сокеты работают без установки соединения и не обеспечивают ни идентификации отправителя, ни контроля успешности доставки данных, зато они быстрее потоковых, опираються на протокол UDP. Сырые сокеты, они предоставляют возможность ручного формирования TCP\IP пакетов. Програмирование сокетов идет поэтапно:
Таблица – Функции по работе с сокетами
Пример TCP #include <stdio.h> #include <string.h> // Для работы с библиотекой Winsock2 в исходный текст нужно включить директиву #include <winsock2.h>, //а в командной строке компоновщика указать ws2_32.lib. Библиотека Winsock2 должна быть указана раньше, // чем библиотека Windows. #include <winsock2.h> #include <windows.h>
#define PORT 31337 // Порт, через который идет подключение к серверу....21,80,25,110 и т.п. #define SERVERADDR "127.0.0.1" // Адрес сервера
int main ( int argc, char* argv [ ] ) { char buff [ 1024 ] ; printf ( "TCP Client \n" ); // ну, тут и так понятно //Перед началом использования библиотеки ее необходимо подготовить к работе с помощью вызова функции // WSAStartup(Ver, lpWSAData), передав ей в старшем байте номер требуемой версии, а в младшем подверсии. // Аргумент lpWSAData должен указывать на структуру WSADATA, в которую при успешной инициализации //будет занесена информация о производителе библиотеки. Если инициализация не удалась, то функция //возвращает не нулевое значение. if ( WSAStartup ( 0x202, ( WSADATA * ) &buff [ 0 ] ) ) { printf ( " WSAStart error %d \n ", WSAGetLastError ( ) ); return -1; } // Создаем сокет socket ( int af, int type, int protocol ). Первый слева аргумент указывает на семейство использу- //емых протоколов, AF_INET - используеться при создании интернет приложений. SOCK_STREAM - тип //создаваемого сокета, SOCK_STREAM (потоковый) или SOCK_DGRAM (дейтаграммный) или SOCK_RAW //(сырой).Последний аргумент задает тип создаваемого сокета, нулевое значение соответствует выбору по //умолчанию, ТСР - для потоковых, и UDP - дейтограммных. //Если функция завершилась успешно то она возвращает дескриптор сокета. SOCKET my_sock ; my_sock=socket ( AF_INET, SOCK_STREAM, 0 ); if ( my_sock < 0 ) // { printf (" Socket ( ) error %d \n ", WSAGetLastError ( ) ); return -1; } //Далее расмотрим установку соединения. Заполнение структуры sockaddr_in : sockaddr_in dest_addr ; dest_addr.sin_family=AF_INET; //инет коннектинг dest_addr.sin_port=htons ( PORT ); //порт HOSTENT *hst; // хост // Преобразование ip-адреса из символьного в сетевой формат. if ( inet_addr ( SERVERADDR ) !=INADDR_NONE ) dest_addr.sin_addr=inet_addr ( SERVERADDR) ; else //Осуществляем поптыку получения ip-адреса по доменному имени сервера. if ( hst=gethostbyname ( SERVERADDR ) ) ( ( unsigned long * ) &dest_addr.sin_addr ) [ 0 ] = //hst->h_addr_list содержит массив указателей на адреса, НО не массив адресов ( ( unsigned long ** ) hst->h_addr_list ) [ 0 ] [ 0 ] ; //Если ip-адрес не получен, то работа программы завершаеться else { printf ( " invalid address %s \n ", SERVERADDR ) ; closesocket ( my_sock ) ; WSACleanup ( ) ; return -1; } //После получения адреса сервера, попытаемся установит соединение.Для этого мы вызовем функцию connect // (SOCKET s, sockaddr * name, len). Первый элемент -SOCKET- это дескриптор сокета, второй - //указатель на структуру sockaddr, содержащую в себе адрес (ip) и порт, последний аргумент сообщает о размере // sockaddr. // Если по каким-то причинам установить соединение не удаеться, то функция возвращает не нулевое значение. if (connect ( my_sock, ( sockaddr * ) &dest_addr, sizeof ( dest_addr ) ) ) { printf (" Connect error %d \n ", WSAGetLastError ( ) ); return -1; }
printf (" Соединение с %s успешно установлено \n\ Type quit for quit \n\n" , SERVERADDR ); //Далее начинаеться чтение и передача сообщений. int nsize; while ( ( nsize = recv ( my_sock, &buff[0], sizeof ( buff ) -1,0 ) ) !=SOCKET_ERROR ) { //Ставим завершающий ноль в конце строки buff[ nsize ] =0; //Выводим на экран printf ( " S=>C: %s ", buff ) ; //Читаем пользовательский ввод с клавиатуры printf ( "S<=C: " ) ; fgets ( &buff [ 0 ] , sizeof ( buff ) -1, stdin ); //После того, как ввели слово quit, выходим..... if ( !strcmp ( &buff [ 0 ], "quit \n " ) ) { printf ( " Exit " ); closesocket ( my_sock ) ; //выход правильный WSACleanup ( ) ; return 0; } //Передача строки клиента серверу send ( my_sock, &buff [ 0 ], nsize, 0 ) ; }
printf ( " Recv error %d \n", WSAGetLastError ( ) ); closesocket ( my_sock ) ; WSACleanup ( ) ; return -1; }
Пример UDP //Пример простого UDP-клиента #include<stdio.h> #include<string.h> #include<winsock2.h> #include<windows.h>
#define PORT 31337 #define SERVERADDR "127.0.0.1"
int main ( int argc, char* argv [ ] ) { char buff [ 10*1024 ]; printf (" UDP Client \n"); //Подключение библиотеки if (WSAStartup ( 0x202, ( WSADATA *) &buff [ 0 ] )) { printf (" WSAStartup error: %d\n ", WSAGetLastError ( ) ); return -1; } //Создание сокета SOCKET name_sock=socket ( AF_INET, SOCK_DGRAM, 0 ); if ( name_sock==INVALID_SOCKET ) { printf (" socket ( ) error: %d \n ", WSAGetLastError ( ) ); WSACleanup ( ); return -1; } //Обмен сообщений с сервером HOSTENT *hst; sockaddr_in dest_addr;
dest_addr.sin_family=AF_INET; dest_addr.sin_port=htons ( PORT ); //Определение IP-адреса узла if (inet_addr ( SERVERADDR )) dest_addr.sin_addr.s_addr=inet_addr ( SERVERADDR ); else if ( hst=gethostbyname ( SERVERADDR )) dest_addr.sin_addr.s_addr=((unsigned long **) //функция gethostbyname ожидает на входе ТОЛЬКО доменные имена hst->h_addr_list)[0][0]; else { printf ("Unknown host: %d \n", WSAGetLastError ( )); closesocket ( name_sock ); WSACleanup ( ); return -1; } while (1) { //Чтение сообщения с клавиатуры printf ("S<=C: "); fgets (&buff [0], sizeof (buff) -1, stdin); if (!strcmp(&buff [0], "quit \n")) break; //передача сообщений на сервер sendto(name_sock, &buff [0], strlen ( &buff [0] ), 0,(sockaddr *) &dest_addr, sizeof(dest_addr)); //Прием сообщений с сервера sockaddr_in server_addr; int server_addr_size=sizeof (server_addr);
int n=recvfrom (name_sock, &buff [0], sizeof(buff)-1,0,(sockaddr *) &server_addr, &server_addr_size); if ( n==SOCKET_ERROR) { printf ("recvfrom ( ) error: %d\n", WSAGetLastError ( ) ); closesocket(name_sock); WSACleanup ( ); return -1; } buff [n]=0; //Вывод принятого сообщения с сервера на экран printf("S=>C: %s", &buff [0]); } //Выход closesocket (name_sock); WSACleanup ( ); return 0; } |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2018-06-01; просмотров: 205. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |