Рассмотрим для примера структуру sockaddr_in.




Теоретическое введение.

Сокет (socket) - это конечная точка сетевых коммуникаций. Он является чем-то вроде "портала", через которое можно отправлять байты во внешний мир

С каждым сокет связываются три атрибута: домен, тип и протокол.

int socket(int domain, int type, int protocol);

Домен определяет пространство адресов, в котором располагается сокет, и множество протоколов, которые используются для передачи данных. Чаще других используются домены Unix и Internet, задаваемые константами AF_UNIX и AF_INET соответственно (префикс AF означает "address family" - "семейство адресов"). При задании AF_UNIX для передачи данных используется файловая система ввода/вывода Unix. В этом случае сокеты используются для межпроцессного взаимодействия на одном компьютере и не годятся для работы по сети. Константа AF_INET соответствует Internet-домену. Сокеты, размещённые в этом домене, могут использоваться для работы в любой IP-сети. Существуют и другие домены (AF_IPX для протоколов Novell, AF_INET6 для новой модификации протокола IP - IPv6 и т. д.).

Тип сокета определяет способ передачи данных по сети. Чаще других применяются:

SOCK_STREAM. Передача потока данных с предварительной установкой соединения. Обеспечивается надёжный канал передачи данных, при котором фрагменты отправленного блока не теряются, не переупорядочиваются и не дублируются. Совместное использование с параметром AF_INET связывает сокет с протоколом TCP.

SOCK_DGRAM. Передача данных в виде отдельных сообщений (датаграмм). Предварительная установка соединения не требуется. Обмен данными происходит быстрее, но является ненадёжным: сообщения могут теряться в пути, дублироваться и переупорядочиваться. Допускается передача сообщения нескольким получателям (multicasting) и широковещательная передача (broadcasting). Совместное использование с параметром AF_INET связывает сокет с протоколом UDP

SOCK_RAW. Этот тип присваивается низкоуровневым (т. н. "сырым") сокетам. Их отличие от обычных сокетов состоит в том, что с их помощью программа может взять на себя формирование некоторых заголовков, добавляемых к сообщению.

.). При передаче в функцию bind указатель на эту структуру приводится к указателю на sockaddr.

Рассмотрим для примера структуру sockaddr_in.

struct sockaddr_in {

short int sin_family; // Семейство адресов

unsigned short int sin_port; // Номер порта

struct in_addr sin_addr; // IP-адрес

unsigned char sin_zero[8]; // "Дополнение" до размера структуры sockaddr

};

На стороне клиента для установления соединения используется функция connect, которая имеет следующий прототип.

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

 

Здесь sockfd - сокет, который будет использоваться для обмена данными с сервером, serv_addr содержит указатель на структуру с адресом сервера, а addrlen - длину этой структуры.

Функция send используется для отправки данных и имеет следующий прототип.

int send(int sockfd, const void *msg, int len, int flags);

Здесь sockfd - это, как всегда, дескриптор сокета, через который мы отправляем данные, msg - указатель на буфер с данными, len - длина буфера в байтах, а flags - набор битовых флагов, управляющих работой функции

Для чтения данных из сокета используется функция recv.

int recv(int sockfd, void *buf, int len, int flags);

В целом её использование аналогично send

Закончив обмен данными, закройте сокет с помощью функции close (под Windows closesocket).Это приведёт к разрыву соединения.

closesocket(tcp_socket);

close(tcp_socket);

 

Код программы (С++):

#include <iostream.h> //для cin и cout

#include <winsock2.h> //для сокетов

char bufRus[1024]; //буфер для функции Rus

char* Rus(const char* text) //функция для вывода кириллицы в консоль

{

CharToOem(text, bufRus); //функция для перевода кодировки

return bufRus;

}

int main()

{

WSADATA Data;

WSAStartup(MAKEWORD(2,2),&Data); //подготовка к работе библиотеки Winsock

char message[1024]; //массив символов для сообщения

char buf[1024] = ""; //массив символов для принятого сообщения

SOCKET sock; //объявление сокета

struct sockaddr_in addr;

cout<<Rus("Клиент работает по протоколу UDP\n");

sock = socket(AF_INET, SOCK_DGRAM, 0);

addr.sin_family = AF_INET; //используется пространство адресов Internet

addr.sin_addr.s_addr = inet_addr ("127.0.0.1");

while(1)

{

cout<<Rus("\nВведите ваше сообщение или напишите \"daytime\" для получения текущего времени: \n");

gets (message); //ввод сообщения

if (strcmp(message, "daytime") == 0)addr.sin_port = htons(13);

else addr.sin_port = htons(7);

cout<<Rus("Получено: ");

sendto(sock, message, sizeof(message), 0, (struct sockaddr *)&addr, sizeof(addr));

recvfrom(sock, buf, 1024, 0, NULL, NULL);

cout<<Rus(buf)<<endl;

}

closesocket(sock); //закрытие сокета

WSACleanup(); //деинициализация библиотеки WINSOCK

system("pause"); //пауза

return 0;}

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-27 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: