Студопедия
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Обмен датаграммами

Читайте также:
  1. Биохимические основы обмена белков, жиров, углеводов, гормонов, витаминов, медиаторов.
  2. Бухгалтерский учёт валютно-обменных операций банков
  3. ВАЛЮТНО-ОБМЕННЫЕ ОПЕРАЦИИ
  4. Валютно-обменные операции
  5. Валютный обменный пункт
  6. Великий шелковый путь. Начало контактов и обменных связей восходит к III—II тыс. до н. э.
  7. Взаимосвязь азотистого обмена с другими видами обменов
  8. Взаимосвязь липидного обмена с другими видами обменов
  9. Взаимосвязь углеводного обмена с другими видами обменов
  10. Влияет на теплообмен и движение воздуха.

Как уже говорилось, датаграммы используются в программах довольно редко. В большинстве случаев надёжность передачи критична для приложения, и вместо изобретения собственного надёжного протокола поверх UDP программисты предпочитают использовать TCP. Тем не менее, иногда датаграммы оказываются полезны. Например, их удобно использовать при транслировании звука или видео по сети в реальном времени, особенно при широковещательном транслировании.

 

Поскольку для обмена датаграммами не нужно устанавливать соединение, использовать их гораздо проще. Создав сокет с помощью socket и bind, вы можете тут же использовать его для отправки или получения данных. Для этого вам понадобятся функции sendto и recvfrom.

 

int sendto(int sockfd, const void *msg, int len, unsigned int flags,

const struct sockaddr *to, int tolen);

int recvfrom(int sockfd, void *buf, int len, unsigned int flags,

struct sockaddr *from, int *fromlen);

 

Функция sendto очень похожа на send. Два дополнительных параметра to и tolen используются для указания адреса получателя. Для задания адреса используется структура sockaddr, как и в случае с функцией connect. Функция recvfrom работает аналогично recv. Получив очередное сообщение, она записывает его адрес в структуру, на которую ссылается from, а записанное количество байт - в переменную, адресуемую указателем fromlen. Как мы знаем, аналогичным образом работает функция accept.

 

Некоторую путаницу вносят присоединённые датаграммные сокеты (connected datagram sockets). Дело в том, что для сокета с типом SOCK_DGRAM тоже можно вызвать функцию connect, а затем использовать send и recv для обмена данными. Нужно понимать, что никакого соединения при этом не устанавливается. Операционная система просто запоминает адрес, который вы передали функции connect, а затем использует его при отправке данных. Обратите внимание, что присоединённый сокет может получать данные только от сокета, с которым он соединён.

 

Для иллюстрации процесса обмена датаграммами я написал две небольшие программы - sender (листинг 3) и receiver (листинг 4). Первая отправляет сообщения "Hello there!" и "Bye bye!", а вторая получает их и печатает на экране. Программа sender демонстрирует применение как обычного, так и присоединённого сокета, а receiver использует обычный.

 

Листинг 3. Программа sender.

 

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

 

char msg1[] = "Hello there!\n";

char msg2[] = "Bye bye!\n";

 

int main()

{

int sock;

struct sockaddr_in addr;

 

sock = socket(AF_INET, SOCK_DGRAM, 0);

if(sock < 0)

{

perror("socket");

exit(1);

}

 

addr.sin_family = AF_INET;

addr.sin_port = htons(3425);

addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

sendto(sock, msg1, sizeof(msg1), 0,

(struct sockaddr *)&addr, sizeof(addr));

 

connect(sock, (struct sockaddr *)&addr, sizeof(addr));

send(sock, msg2, sizeof(msg2), 0);

 

close(sock);

 

return 0;

}

 

Листинг 4. Программа receiver.

 

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <stdio.h>

 

int main()

{

int sock;

struct sockaddr_in addr;

char buf[1024];

int bytes_read;

 

sock = socket(AF_INET, SOCK_DGRAM, 0);

if(sock < 0)

{

perror("socket");

exit(1);

}

 

addr.sin_family = AF_INET;

addr.sin_port = htons(3425);

addr.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)

{

perror("bind");

exit(2);

}

 

while(1)

{

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

buf[bytes_read] = '\0';

printf(buf);

}

 

return 0;

}




Дата добавления: 2014-12-19; просмотров: 99 | Поможем написать вашу работу | Нарушение авторских прав




lektsii.net - Лекции.Нет - 2014-2025 год. (0.008 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав