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

Міністерство освіти і науки, молоді та спорту України

Кіровоградський національний технічний університет

Кафедра програмного забезпечення

Дисципліна : Обчислювальні системи

Лабораторна робота6

Тема: «Комунікаційне програмне забезпечення рівня користувача. Виклик віддаленої процедури».

Виконала: студентка

групи КІ-09-2

Змеул О.М.

Перевірив: викладач

Доренський О.П.

м. Кіровоград

2012 рік

Завдання:

Напишіть на мові С функції, які могли б використовувати як клієнтський так і серверний сурогати для виконання RPC - виклику стандартної функції printf, а також головний модуль для тестування цих функцій.

Клієнт та сервер повинні спілкуватися за допомогою структури даних, яка передається по мережі. Накладіть розумні обмеження на довжину рядка, формату та число, типи та розміри змінних, які будуть приймати клієнтські сурогати.

Лістинг програми:

/* Клієнтський процес */

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <ctype.h>

#include <string.h>

#include <stdarg.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#define SIZE sizeof (struct sockaddr_in)

#define RPC_PRINTF 1

struct rpc_header{

int type, len;

};

char host_addr[] = "192.168.1.1";

int rpc_printf(const char *format, ...);

int main(void)

{

int code;

code = rpc_printf("Integer number\t %i\n", 2012);

printf("rpc_printf returned code: %i\n", code);

code = rpc_printf("Double number\t %f\n", 100.001);

printf("rpc_printf returned code: %i\n", code);

code = rpc_printf("Character\t %c\n", 'i');

printf("rpc_printf returned code: %i\n", code);

code = rpc_printf("String\t\t %s\n", "some string");

printf("rpc_printf returned code: %i\n", code);

code = rpc_printf("\n");

printf("rpc_printf returned code: %i\n", code);

code = rpc_printf("by Zmeul\n");

printf("rpc_printf returned code: %i\n", code);

return 0;

}

int rpc_printf(const char *format, ...) {

char str[256];

va_list vl;

va_start(vl, format);

vsprintf(str, format, vl);

va_end(vl);

int sockfd;

char c, rc;

struct sockaddr_in server;

server.sin_family = AF_INET;

server.sin_port = 9000;

struct rpc_header h;

int code;

/* Перетворює та зберігає IP адресу сервера */

server.sin_addr.s_addr = inet_addr(host_addr);

/* Створення сокету */

if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {

return 0;

}

/* З'єднує сокет з сервером */

if (connect(sockfd,(struct sockaddr* ) &server, SIZE) ==-1) {

return 0;

}

/* Цикл обміну даними з серврером */

h.type = RPC_PRINTF;

h.len = strlen(str);

send(sockfd, &h, sizeof(struct rpc_header), 0);

send(sockfd, str, h.len, 0);

if (recv(sockfd, &code, sizeof(int), 0) > 0) {

close(sockfd);

return code;

}

else{

close(sockfd);

return 0;

}

};

Лістинг програми:

/* Серверний процес */

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <ctype.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <signal.h>

#define SIZE sizeof(struct sockaddr_in)

#define RPC_PRINTF 1

void catcher(int sig);

int newsockfd;

struct header{

int type, len;

};

main()

{

int sockfd;

char c;

struct sockaddr_in server = {AF_INET, 9000, INADDR_ANY};

static struct sigaction act;

act.sa_handler = catcher;

sigfillset(&(act.sa_mask));

sigaction(SIGPIPE, &act, NULL);

/* Створюємо сокет*/

if (( sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)

{

perror("Error call: socket ");

exit (1);

}

/* Зв'язує адресу з сокетом */

if (bind(sockfd, (struct sockaddr*)&server, SIZE) == -1)

{

perror("Error call: bind ");

exit (1);

}

/* Включає прийом з'єднань */

if (listen(sockfd, 5) == -1)

{

perror("Error call: listen");

exit(1);

}

for (;;)

{

/* Приймаємо запит на з'єднання */

if ((newsockfd = accept(sockfd, NULL, NULL)) == -1)

{

perror("Error call: accept");

continue;

}

/* Створює дочірній процес для роботи з з'єднанням */

if (fork() == 0)

{

struct header h;

char *str = calloc(100, sizeof(char));

recv(newsockfd, &h, sizeof(struct header), 0);

if (h.type == RPC_PRINTF) {

recv(newsockfd, str, h.len, 0);

int code = printf("%s",str);

send(newsockfd, &code, sizeof(int), 0);

}

/* Після того, як клієнт перестав передавати дані сокет може бути закритим і дочірній процес завершує роботу */

close (newsockfd);

exit (0);

}

/* У батьківському процесі newsockfd не потрібен */

close (newsockfd);

}

}

void catcher(int sig)

{

close(newsockfd);

exit(0);

}

Рис. 1 – Обмін даними

Соседние файлы в папке Вычислительные системы