Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Lab1_5-12IT3-Divin / Отчет

.docx
Скачиваний:
98
Добавлен:
18.05.2015
Размер:
22.75 Кб
Скачать

Министерство образования Республики Беларусь

ПОЛОЦКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

Кафедра вычислительных систем и сетей

Лабораторная работа1.5

по курсу «Операционные системы и системное программирование»

«Программирование сокетов в Linux»

Студент группы 12-ИТ-3

Выполнил: Дивин К.П.

Полоцк 2014

ЦЕЛЬ РАБОТЫ:

Создание распределенных сетевых приложений.

ХОД РАБОТЫ

  1. Написать программу сервер согласно индивидуальному заданию.

  1. Написать программу согласно индивидуальному заданию.

  2. Связать работу двух приложений;

Реализовать программу по созданию множества мелких файлов из одного большого, размер маленьких файлов произвольныйю Сервер получает запрос от клиента и возращает ему кусочек файла. Протокол взаимодействия UDP;

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

Сервер:

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "find.h"

#define COUNT 5

int main()

{

int sock;

struct sockaddr_in addr;

char msg1[50], msg2[50];

int bytes_read;

char *tmp = (char*)calloc(1024, sizeof(char));

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)

{

struct sockaddr_in from;

int from_len;

bytes_read = recvfrom(sock, msg1, 50, 0,

(struct sockaddr *)&from, &from_len);

msg1[bytes_read] = '\0';

printf("Get msg: %s\n", msg1);

fflush(stdout);

bytes_read = recvfrom(sock, msg2, 50, 0,

(struct sockaddr *)&from, &from_len);

msg2[bytes_read] = '\0';

printf("Get msg: %s\n", msg2);

fflush(stdout);

int param = 0;

param = atoi(msg2);

tmp = split_file(msg1, COUNT, param);

printf("Sending Results...\n");

fflush(stdout);

sendto(sock, tmp, strlen(tmp), 0,

(struct sockaddr *)&from, from_len);

}

return 0;

}

Подключенная библиотека “find.h”, содержит в себе функцию для разбивания файла на определенное количество кусков. Функция возвращает строку содержащую имя файла, который является тем самым искомым куском файла.

Описание переменных и функций, использованных при написании:

struct sockaddr_in {

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

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

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

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

};

Здесь поле sin_family содержит идентификатор домена, в sin_port записывается номер порта, sin_addr - IP-адрес хоста.

s = socket(AF_INET, SOCK_DGRAM, 0) - функция определения сокета (AF_INET – домен Internet; SOCK_DGRAM – способ передачи данных по сети, а именно передача потока данных с помощью датаграмм.

addr.sin_family = AF_INET; - семейство адресов;

addr.sin_port = htons(3425); - номер порта;

addr.sin_addr.s_addr = htonl(INADDR_ANY); - преобразование числа из порядка хоста в сетевой порядок.

int bind(s, (struct sockaddr*)&addr, sizeof(addr)) – функция для явного связывания сокета с некотромы адресом (s – дескриптор сокета; addr – указатель на структуру адреса; sizeof(addr) – длина структуры адреса).

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

Клиент:

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main()

{

char msg1[50];

char msg2[50];

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);

printf("Enter filename please.\n");

scanf("%s", msg1);

sendto(sock, (const void*)msg1, sizeof(msg1), 0,

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

printf("Enter the number of pieces of the file you want to get.\n");

scanf("%s", msg2);

sendto(sock, (const void*)msg2, sizeof(msg2), 0,

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

char *tmp = (char*)calloc(1024, sizeof(char));;

int bytes_read;

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

tmp[bytes_read] = '\0';

printf("Filename:\n%s\n", tmp);

fflush(stdout);

return 0;

}

Вывод:

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

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

Соседние файлы в папке Lab1_5-12IT3-Divin