Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция 9.docx
Скачиваний:
88
Добавлен:
17.06.2016
Размер:
65.52 Кб
Скачать

Листинг 9.9- Простейший udp- сервер

#define PORT 1153

#define BUFSIZE 2048

int main(int argc, char **argv) {

struct sockaddr_in myaddr; /* наш адрес */

struct sockaddr_in remaddr;/* удаленный адрес */

socklen_t addrlen = sizeof(remaddr); /*длина адресов */

int recvlen; /* число полученных байт */

int fd; /* наш сокет */

unsigned char buf[BUFSIZE]; /* буфер приема данных */

/* создаем UDP сокет */

if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {

perror("невозможно создать сокет\n");

return 0; }

/* привязываем сокет к любому IP – адресу и специфицированному порту */

memset((char *)&myaddr, 0, sizeof(myaddr));

myaddr.sin_family = AF_INET;

myaddr.sin_addr.s_addr = htonl(INADDR_ANY);

myaddr.sin_port = htons(PORT);

if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {

perror("bind failed"); return 0; }

/* принимаем в цикле данные, печатаем то что получили */

for (;;) {

printf("ждем на порте %d\n", PORT);

recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);

printf("получено %d байт\n", recvlen);

if (recvlen > 0) {

buf[recvlen] = 0; printf("получено сообщение: \"%s\"\n", buf); } }

/*бесконечно */

}

Двунаправленный обмен

В случае если сервер хочет ответить клиенту, от которого он принял дейтаграмму можно воспользоваться адресной информацией, полученной в результате вызова recvfrom (см выше). Данные об адресе и порте клиента, с которого была отправлена дейтаграмма помещаются в структуру remaddr:

recvlen = recvfrom(s, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);

Сервер теперь может использовать этот адрес в функции sendto и отправить сообщение отправителю.

sendto(s, buf, strlen(buf), 0, (struct sockaddr *)&remaddr, addrlen)

Закрытие сокета.

В отличие от TCP – сокетов нет необходимости вызывать метод shutdown для закрытия сокета или уничтожения соединения (т.к. его фактически нет в случае UDP). Тем не менее необходимо освободить дескриптор сокета в ядре, что может быть осуществлено при помощи вызова close().

close(fd);

Соседние файлы в папке Лекции