MC823 Atividade 5 Chamada de Procedimentos Remotos

Documentos relacionados
Prof. A. G. Silva. 13 de novembro de Prof. A. G. Silva INE5603 Introdução à POO 13 de novembro de / 1

MC823 Atividade 1: Cliente/Servidor TCP Iterativo. 3 Modificando o servidor para retornar data e hora

Computação 2. Aula 8. Profª. Fabiany Arquivos

Computação 2. Aula 9. Diego Addan Arquivos

OProtocolo RPC é um dos protocolos de aplicação mais utilizados, pois permite

USP - ICMC - SSC SSC o. Semestre Disciplina de Introdução à Computação para Engenharia Ambiental

Listas (cont.) K&R: Capitulo 6. Lista Simplesmente Ligada IAED, 2012/2013. Conjunto de nós. Cada nó contém. head NULL. typedef struct node {

Disciplina de Linguagem de Programação e Aplicações [ Eng. Elétrica / Automação ]

Sistemas de Operação (2018/2019) Ficha 4

Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria

USP - ICMC - SSC SSC o. Semestre Disciplina de Linguagem de Programação e Aplicações [ Eng. Elétrica / Automação ]

USP - ICMC - SSC SSC o. Semestre Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria

Departamento de Sistemas de Computação Universidade de São Paulo Introdução a Ciência de Computação I. Aula 13 Arquivos

INSTITUTO FEDERAL DE EDUCAÇÃO, CIÊNCIA E TECNOLOGIA RIO GRANDE DO NORTE

Trabalho 02: Cliente e Servidor em C

Existe uma quantidade de informação que pode ser armazenada para resolver o problema.

Arquivos em C Parte 2

CAP. IX - MANIPULAÇÃO DE ARQUIVOS Generalidades sobre Arquivos. 9.2 Abertura e Fechamento de Arquivos. Operações com arquivos:

Programação II. Arquivos - Conceito. Arquivos

Fundamentos de Programação 1

Entrada e Saída Exercício. Linguagem Java. Adenilso da Silva Simão 01/09/05

Universidade de São Paulo São Carlos Instituto de Ciências Matemáticas e de Computação. Arquivos em C

Verificando corretude da triangulação

Linguagem C Ficheiros Compilação Separada

Manipulação de Ficheiros

1/24 FICHEIROS DE TEXTO

Sistemas de Computação Sistemas de Arquivos

Projecto hipotético para resolvermos hoje

JavaTM RMI - Remote Method Invocation

Aula 26 - Arquivos. Prof. Laura Silva de Assis. Engenharia da Computação. CEFET/RJ - Centro Federal de Educação Tecnológica Celso Suckow da Fonseca

TÉCNICAS DE PROGRAMAÇÃO

Laboratório de Introdução à Ciência da Computação I

13a. Aula Manipulação de arquivos

Computadores Digitais 2. Prof. Rodrigo de Souza Couto

Reader e Writer para streams de caracteres (texto).

Sistemas Distribuídos

Aula 16: Manipulação de Arquivos em C

Arquivos em C. Material da Prof. Ana Eliza

Leitura de Arquivos. Prof. Fabrício Olivetti de França

Outline. 33. Manipulação de arquivos DIM

Programação para Computação 13ª Aula

Memória compartilhada

Bravas shield sample app 2017

Arquivos. Programação de Computadores I. Natália Batista.

Aula 16. Ficheiros de texto

INF 1620 P2-14/10/05 Questão 1 Nome:

Básico: estrutura de programa, sintaxe Interface com linha de comando

USP - ICMC - SSC SSC o. Semestre Disciplina de Introdução à Ciência da Computação ICC 1 - Teoria

Universidade Federal de Uberlândia Faculdade de Computação. Linguagem C: Manipulação de arquivos

Comunicação Inter-Processo em Unix. Pipes FIFO (Named Pipes) Pipes

Programando sistemas distribuídos com objetos distribuídos na rede TCP/IP. Prof. Me. Sérgio Carlos Portari Júnior

Aluno: Valor Nota Q1 3.0 Q2 2.5 Q3 2.5 Q4 2.0 Total 10.0

Java RMI. RMI Remote Method Invocation. Chamadas Remotas de Procedimentos (RPC) RPC - Implementação

Programação Orientada por Objectos com Java. Ademar Aguiar. MRSC, Programação em Comunicações

Sistemas Distribuídos

C Arquivos. Adriano Cruz 21 de julho de Instituto de Matemática Departamento de Ciência da Computação UFRJ

Programação Estruturada e Orientada a Objetos

Tipos, Literais, Operadores

Tipos, Literais, Operadores

RMI e RPC. RPC significou um passo muito grande em direcção à

Comunicação entre Processos

Manipulação de Arquivos

Introdução. Manipulação de arquivos em C. Estrutura de Dados II Prof Jairo Francisco de Souza

Como pôde verificar, a criação de um objecto do tipo File não cria o ficheiro em disco.

Bravas shield light sample app 2017

INF 1620 P4 11/12/06 Questão 1 Nome:

Introdução à Computação II AULA 08 BCC Noturno - EMA896115B

E/S em Arquivo. Para ler ou escrever arquivos é preciso usar ponteiros de arquivo. Um ponteiro de arquivo é uma variável ponteiro do tipo FILE:

Aula 14 Oficina de Programação Tópicos Especiais em C: Arquivos. Profa. Elaine Faria UFU

INF 1620 P2-23/10/04 Questão 1 Nome:

Mestrado em Engenharia Física Tecnológica

Hierarquia de classes. Veja as diversas classes do pacote

Reader e Writer para streams de caracteres (texto).

Linguagem C. Armazenamento de Dados em Arquivos - Continuação

Chamadas Remotas de Procedimentos (RPC)

Estruturas de Dados. Módulo 15 - Arquivos. 2/6/2005 (c) Dept. Informática - PUC-Rio 1

EPs 1 e 2. EP2: veja. EP1: veja

rpcgen - Funcionamento rpcgen Exemplo de arquivo de especificação: Passo 1: Construir uma Aplicaçao Convencional

MAC-115 Introdução à Computação para Ciências Exatas e Tecnologia IO Terceiro Exercício-Programa Entregar até 09/11/2007

1/22 FICHEIROS BINÁRIOS

Aula: ARQUIVOS. Introdução à Ciência da Computação I Simone Senger Souza. ICMC/USP São Carlos

Exemplo de Aplicação Distribuída Serviço de Nomes Gerente de Segurança. Callbacks. Prof a Ana Cristina B. Kochem Vendramin DAINF / UTFPR

Sistemas Distribuídos

Aula 26: Arquivos de texto

Computação 2. Aula Profª. Fabiany Listas Duplamente Encadeadas

Alocação Dinâmica de Memória - Exercício

Num sistema de objectos distribuídos, dois conceitos são fundamentais.

Manipulação de Arquivos

INF 1620 P4-01/07/08 Questão 1 Nome:

Depuração e Teste de programas C C Depuração e teste de programas C

RESPOSTA: import java.util.arraylist; import java.util.list; class CarrinhoDeCompras2 { List<Produto> produtos;

Prova 2 PMR3201 1o. semestre 2016 Prof. Thiago Martins

LINGUAGEM C: ARQUIVOS

Programação de Computadores II

INF 1620 P3-27/11/04 Questão 1 Nome:

INF 1620 P1-16/09/06 Questão 1 Nome:

Linguagens de Programação Conceitos e Técnicas. Variáveis e Constantes

INF 1620 P3-25/11/05 Questão 1 Nome:

Introdução a Programação. Manipulando Arquivos em Modo Texto

Transcrição:

MC823 Atividade 5 Chamada de Procedimentos Remotos Gustavo Sverzut Barbieri <ra008849@ic.unicamp.br> 1 Introdução Este trabalho tratou de chamadas de procedimentos remotos usando duas técnicas comumente utilizadas, o RPC Remote Procedure Call elaborado em meados da década de 70 e utilizado amplamente a partir da década de 80 com serviços como NFS e NIS, e o RMI Remote Method Invocation elaborado também pela Sun Microsystems para sua nova arquitetura, o Java. Como exercício foi implementado um servidor de arquivos, bem básico. A implementação foi idêntica em ambas as linguagens, a fim de testar o desempenho comparativo do sistema de chamadas, não explorando peculiaridades de cada técnica. Esta não utilizou guardar estado no servidor, a cada chamada o cliente envia o nome do arquivo, um deslocamento a partir do inicio deste e a quantidade de bytes a serem lidas; o servidor abre o arquivo, desloca-se para a posição requerida e tenta ler a quantidade desejada, fecha o arquivo o retorna a quantidade que ele conseguiu ler, seguido de um estado que pode indicar sucesso, erro ou fim de arquivo e então os dados. Note que para cada requisição faz-se a abertura, reposicionamento e fechamento do arquivo, deteriorando a performance 1. Note também que devido a um limite de 8Kb dos pacotes RPC/UDP, utilizamos um tamanho de dados de 8000 bytes em ambas as implementações. 2 Comparativo de Performance Para medir a diferença de performance entre os sistemas, foi medido o tempo para transportar um arquivo grande e outro pequeno usando o RPC e o RMI, os tempos e taxas estão nas tabelas de 2 a 2. Todas a comunicação foi feita na mesma maquina, usando a placa de rede, eliminando assim o gargalo da rede, porem assegurando que o RPC ou RMI não utilizasse algum artificio para o caso da interface loopback. A principio cogitou-se a comparação com um sistema real e otimizado para troca de arquivos, wget/http, porem o resultado foi muito distante (90Mb/s). Isso se deve ao fato do servidor http (apache) transferir todos os dados de forma sequencial (stream) e não precisar abrir-procurar-fechar o arquivo a cada requisição e as implementações RPC e RMI enviarem e esperarem (stop and wait) e ainda executar operações de arquivo supra citadas. No entanto as tabelas 1 Em geral o sistema operacional mantém um cache para os arquivos abertos, além disso existe o custo de reposicionamento da cabeça de leitura e o cache do disco que em geral tem 2Mb e nos testes era utilizados apenas 8Kb. 1

servem de comparação entre ambos os sistemas, sendo o RMI cerca de 24 vezes mais lento 2. Para certificar o quanto as operações de arquivos e de alocação de memória (no Java) influenciavam no desempenho, criei uma versão boba dos programas as quais transmitiam 10Mb sem ler do disco e usando apenas variáveis estáticas no servidor. O resultado foi ainda mais surpreendente: 170Mb/s para o RPC, 11Mb/s para o RMI, sendo este 15 vezes mais lento. Tentativa Tempo (ms) Taxa (MB/s) 1 < 1 2 < 1 3 < 1 4 < 1 5 < 1 Media < 1 Tabela 1: RPC com arquivo pequeno 1Kb. Tentativa Tempo (ms) Taxa (MB/s) 1 887.0 13.6 2 717.0 16.8 3 729.0 16.6 4 886.0 13.6 5 777.0 15.5 Media 799.2 15.2 Tabela 2: RPC com arquivo grande 12.1Mb. Tentativa Tempo (ms) Taxa (MB/s) 1 9 0.111 1 9 0.111 1 43 0.023 1 5 0.2000 1 42 0.024 Media 21.6 0.093 Tabela 3: RMI com arquivo pequeno 1Kb. 3 Apêndice A 2 Um dos fatores que deteriora a implementação RMI eh o fato do Java alocar o buffer todas as vezes, enquanto que em C este eh uma variavel estática. 2

Tentativa Tempo (ms) Taxa (MB/s) 1 19815 0.605 2 18799 0.638 3 18574 0.646 4 18471 0.649 5 19243 0.623 Media 18980 0.632 Tabela 4: RMI com arquivo grande 12.1Mb. Listing 1: fs.x Descrição de dados para o rpcgen. / f s. x : f i l e server using RPC %# define MAX_FILENAME_SIZE 255 %# define MAX_BLOCK_SIZE 8192 struct fs_get_ret_t int status ; opaque buffer < MAX_BLOCK_SIZE >; ; struct fs_get_param_t long offset ; long count ; string name < MAX_FILENAME_SIZE >; ; struct fs_list_t int status ; long offset ; string name < MAX_FILENAME_SIZE >; ; program FSPROG version FSVERS string CRED () = 1; fs_get_ret_t GET ( fs_get_param_t ) = 2; fs_list_t LIST ( fs_list_t ) = 3; int EXIST ( string ) = 4; = 1; = 0 x20000001 ; Listing 2: fs server.c Implementação das funções do servidor RPC. / This is sample code generated by rpcgen. These are only templates and you can use them as a guideline for developing your own functions. 3

# include "fs.h" # include < sys / types.h> # include < sys / stat.h> # include < unistd.h> # include < dirent.h> # include < errno.h> # include < stdio.h> # include < stdlib.h> # include < string.h> # include < assert.h> # define MAX_FILENAME_SIZE 255 # define MAX_BLOCK_SIZE 8192 static char buffer [ MAX_BLOCK_SIZE ]; extern int errno ; char ** cred_1_svc ( void * argp, struct svc_req * rqstp ) static char * result = " Gustavo Sverzut Barbieri < ra008849@ic. unicamp.br >"; return & result ; int * exist_1_svc ( char ** file, struct svc_req * rqstp ) static int result ; struct stat buf ; result = 0; assert ( file * file ); if ( ( stat ( * file, & buf ) == 0 ) && S_ISREG ( buf. st_mode ) ) result = 1; return & result ; fs_get_ret_t * get_1_svc ( fs_get_param_t * file, struct svc_req * rqstp ) static fs_get_ret_t result ; FILE * fd = NULL ; errno = 0; assert ( file && file ->name && file ->count ); result. status = 0; result. buffer. buffer_len = 0; result. buffer. buffer_val = buffer ; if ( file ->count >= MAX_BLOCK_SIZE ) file ->count = MAX_BLOCK_SIZE ; if ( ( fd = fopen ( file ->name, "r" ) ) == NULL ) result. status = - errno ; return & result ; 4

if ( file -> offset ) fseek ( fd, file ->offset, SEEK_SET ); result. buffer. buffer_len = fread ( buffer, 1, file ->count, fd ); if ( result. buffer. buffer_len!= file ->count ) if ( feof ( fd ) ) result. status = 0; if ( ferror ( fd ) ) result. status = - errno ; result. buffer. buffer_len = 0; result. status = 1; fclose ( fd ); return & result ; fs_list_t * list_1_svc ( fs_list_t * dir, struct svc_req * rqstp ) static fs_list_t result ; DIR *d; struct dirent * f; struct stat fstat ; int dlen, len ; errno = 0; assert ( dir && dir ->name ); result. status = 0; result. offset = 0; result. name = buffer ; buffer [ 0 ] = \0 ; if ( ( d = opendir ( dir ->name ) ) == NULL ) result. status = - errno ; return & result ; if ( dir -> offset ) seekdir ( d, dir -> offset ); dlen = strlen ( dir ->name ); while ( ( f = readdir ( d ) )!= NULL ) len = strlen ( f-> d_name ); 5

if ( len + dlen + 2 >= MAX_BLOCK_SIZE ) result. status = - ENOMEM ; buffer [ 0 ] = \0 ; return & result ; strcpy ( buffer, dir ->name ); buffer [ dlen ] = / ; buffer [ dlen + 1 ] = \0 ; strcat ( buffer, f-> d_name ); stat ( buffer, & fstat ); if ( S_ISREG ( fstat. st_mode ) ) result. offset = telldir ( d ); result. status = 1; closedir ( d ); return & result ; Listing 3: fs client.c Implementação das funções do cliente RPC. / This is sample code generated by rpcgen. These are only templates and you can use them as a guideline for developing your own functions. # include "fs.h" # include < assert.h> # include " interface.c" # include < sys / time.h> # include < errno.h> # define MAX_FILENAME_SIZE 255 # define MAX_BLOCK_SIZE 8192 # define BLOCK_SIZE 8000 extern int errno ; static CLIENT * client = NULL ; void cred () char ** cred = NULL ; char * arg ; assert ( client!= NULL ); while ( 1 ) cred = cred_1 ( ( void *) & arg, client ); if ( cred == NULL ) clnt_perror ( client, " Call failed!" ); printf ( " CREDITS : % s\n", * cred ); if ( clnt_freeres ( client, ( xdrproc_t ) xdr_wrapstring, ( caddr_t ) cred ) ==0 ) fprintf ( stderr, " ERROR : Could not free RPC / XDR result cred (% p)\ n", 6

cred ); void exist ( char * file ) int * exist = NULL ; while (! exist ) exist = exist_1 ( & file, client ); if ( exist == NULL ) clnt_perror ( client, " Call failed!" ); continue ; printf ( "%s, file %s %s.\n", (* exist )? " Yes " : "No", file, (* exist )? " does exist " : " doesn t exist " ); if ( clnt_freeres ( client, ( xdrproc_t ) xdr_int, ( caddr_t ) exist ) == 0 ) fprintf ( stderr, " ERROR : Could not free RPC / XDR result exist (% p)\ n", exist ); void list ( char * dir ) fs_list_t * file ; fs_list_t arg ; assert ( client!= NULL && dir!= NULL ); arg. name = dir ; arg. offset = 0; while ( 1 ) file = list_1 ( & arg, client ); if ( file == ( fs_list_t *) NULL ) clnt_perror ( client, " Call failed!" ); continue ; if ( file -> status == 1 ) puts ( file ->name ); if ( file -> status < 0 ) printf ( " ERROR : Could not read %s : %s\n", arg.name, strerror ( - file -> status ) ); arg. offset = file -> offset ; if ( clnt_freeres ( client, ( xdrproc_t ) xdr_fs_list_t, ( caddr_t ) file ) == 0 ) fprintf ( stderr, " ERROR : Could not free RPC / XDR result file (% p)\ n", file ); if ( arg. offset == 0 ) 7

void get ( char * src, char * dst, int statistics ) fs_get_ret_t * gr; fs_get_param_t gp; FILE * fd; int * exist = NULL ; double size = 0.0 f; char unity [3] = "b"; unsigned long long int ts, count =0; double rate ; char ru [ 3 ] = ""; int status = 0; struct timeval t0, t1, t2, tr; assert ( client!= NULL && src!= NULL && dst ); gp. offset = 0; gp. count = BLOCK_SIZE ; gp. name = src ; while (! exist ) exist = exist_1 ( & src, client ); if ( exist == NULL ) clnt_perror ( client, " Call failed!" ); continue ; if ( * exist == 0 ) fprintf ( stderr, " ERROR : File %s does not exit.\ n", src ); return ; / Free XDR e x i s t if ( clnt_freeres ( client, ( xdrproc_t ) xdr_int, ( caddr_t ) exist ) == 0 ) fprintf ( stderr, " ERROR : Could not free RPC / XDR result exist (% p)\ n", exist ); if ( ( fd = fopen ( dst, "w+" ) ) == NULL ) fprintf ( stderr, " ERROR : Could not open file for writing %s : % s\n", dst, strerror ( errno ) ); return ; gettimeofday ( & t0, NULL ); while ( 1 ) if ( statistics ) gettimeofday ( & t1, NULL ); gr = get_1 ( & gp, client ); if ( gr == ( fs_get_ret_t *) NULL ) clnt_perror ( client, " Call failed!" ); continue ; if ( statistics ) gettimeofday ( & t2, NULL ); 8

timersub ( & t2, & t1, & tr ); ts = ( unsigned long long ) ( tr. tv_sec * 1000000 + tr. tv_usec ); if ( gr -> buffer. buffer_len > ( 1024 * 1024 ) ) strncpy ( unity, "Mb", 3 ); size = ( double )1.0f * gr -> buffer. buffer_len / 1024.0 f / 1024.0 f; if ( gr -> buffer. buffer_len > 1024 ) strncpy ( unity, "Kb", 3 ); size = ( double )1.0f * gr -> buffer. buffer_len / 1024.0 f; strncpy ( unity, "b", 3 ); size = ( double )1.0f * gr -> buffer. buffer_len ; rate = ( double ) gr -> buffer. buffer_len / ( double ) ts; fprintf ( stderr, " STAT : %0.3 f %s in % lld us. [%.1 f b/us ]\n", size, unity, ts, rate ); count += gr -> buffer. buffer_len ; status = gr -> status ; if ( status >=0 ) fwrite ( gr -> buffer. buffer_val, 1, gr -> buffer. buffer_len, fd ); gp. offset += gr -> buffer. buffer_len ; / Free XDR gr if ( clnt_freeres ( client, ( xdrproc_t ) xdr_fs_get_ret_t, ( caddr_t ) gr ) ==0) fprintf ( stderr, " ERROR : Could not free RPC / XDR result gr (% p)\ n", gr ); if ( status == 0 ) printf ( " ERROR : Could not get file %s : %s\n", gp. name, strerror ( - status ) ); / Free XDR gr if ( clnt_freeres ( client, ( xdrproc_t ) xdr_fs_get_ret_t, ( caddr_t ) gr ) ==0) fprintf ( stderr, " ERROR : Could not free RPC / XDR result gr (% p)\ n", gr ); gettimeofday ( & t2, NULL ); timersub ( & t2, & t0, & tr ); ts = ( unsigned long long )(( double ) tr. tv_sec * 1000.0 f + tr. tv_usec / 1000.0 f); if ( count > ( 1024 * 1024 ) ) strncpy ( unity, "Mb", 3 ); size = 1.0f * count / 1024.0 f / 1024.0 f; 9

if ( count > 1024 ) strncpy ( unity, "Kb", 3 ); size = 1.0f * count / 1024.0 f; strncpy ( unity, "b", 3 ); size = 1.0 f * count ; double tv; char tu [ 3 ] = ""; if ( ts > 1000 * 60 * 60 ) strncpy ( tu, "H", 3 ); tv = ( double ) ts / 1000 * 60 * 60; if ( ts > 1000 * 60 ) strncpy ( tu, "M", 3 ); tv = ( double ) ts / 1000 * 60; if ( ts > 1000 ) strncpy ( tu, "s", 3 ); tv = ( double ) ts / 1000; strncpy ( tu, "ms", 3 ); tv = ( double ) ts; rate = ( double ) count / ( ts / 1000.0 f ); if ( rate > ( 1024.0f * 1024.0 f ) ) rate /= 1024.0 f * 1024.0 f; strncpy ( ru, "Mb", 3 ); if ( rate > 1024.0 f ) rate /= 1024.0 f; strncpy ( ru, "Kb", 3 ); strncpy ( ru, "b", 3 ); fprintf ( stderr, " Got file %s (%0.1f % s) in %0.1f % s. [%0.1 f%s/s]\ n", gp.name, size, unity, tv, tu, rate, ru ); gettimeofday ( & t1, NULL ); fclose ( fd ); void fsprog_1 ( char * host ) char *s, * line ; # ifndef DEBUG if ( client ) clnt_destroy ( client ); 10

client = clnt_create ( host, FSPROG, FSVERS, " udp " ); if ( client == NULL ) clnt_pcreateerror ( host ); exit ( EXIT_FAILURE ); # endif / DEBUG ui_init (); while ( ui_stop == 0 ) if ( ( line = readline ( " > " ) ) == NULL ) ui_comm_quit ( "" ); s = stripwhite ( line ); if ( * s!= \0 ) add_history ( s ); ui_execute_line ( s ); free ( line ); # ifndef DEBUG clnt_destroy ( client ); # endif / DEBUG int main ( int argc, char * argv [] ) char * host ; if ( argc < 2 ) printf ( " usage : % s server_host \n", argv [ 0 ] ); exit ( EXIT_FAILURE ); host = argv [ 1 ]; fsprog_1 ( host ); exit ( EXIT_SUCCESS ); 4 Apêndice B Listing 4: GetFileResult.java Estrutura de dados para o retorno do método getfile(). import java. io. Serializable ; public class GetFileResult implements Serializable public byte buffer []; public int count = 0; public int status = 0; public Exception e; 11

public GetFileResult ( int buffer_count ) buffer = new byte [ buffer_count ]; Listing 5: FileServerInterface.java Interface a ser utilizada para relacionamento com o servidor. import java. rmi. Remote ; import java. rmi. RemoteException ; public interface FileServerInterface extends Remote / show c r e d i t s @return c r e d i t s public String cred () throws RemoteException ; / get f i l e chunck from server. @param o f f s e t chunck i n i t pos @param count how many bytes to read (maximum) @return status=0 on EOF, status= 1 on Failure, status=1 on success. I f failure, exception is kept in e, otherwise count bytes are stored in buffer. public GetFileResult getfile ( String name, long offset, int count ) throws RemoteException ; / l i s t dir contents @param name directory name/path @return l i s t of strings public String [] list ( String name ) throws RemoteException ; / t e s t f i l e existence of given f i l e @param name f i l e to t e s t @return true i f exists, f a l s e otherwise public boolean exists ( String name ) throws RemoteException ; import java. io.*; Listing 6: FileServer.java Implementação do servidor. 12

import java. net.*; import java. rmi.*; import java. rmi. server.*; public class FileServer extends UnicastRemoteObject implements FileServerInterface public String cwd ; / show c r e d i t s @return c r e d i t s public String cred () throws RemoteException return new String (" Gustavo Sverzut Barbieri < ra008849@ic. unicamp.br >"); / get f i l e chunck from server. @param o f f s e t chunck i n i t pos @param count how many bytes to read (maximum) @return status=0 on EOF, status= 1 on Failure, status=1 on success. I f failure, exception is kept in e, otherwise count bytes are stored in buffer. public GetFileResult getfile ( String name, long offset, int count ) throws RemoteException GetFileResult gr = new GetFileResult ( count ); try int i; FileInputStream file = new FileInputStream ( new File ( cwd, name )); file. skip ( offset ); // JAVA SUX!!! // Implement i t this way or loose a year reading the docs... gr. count = 0; while ( true ) i = file. read (); if ( i == -1 ) gr. status = 0; gr. status = 1; gr. buffer [ gr. count ] = ( byte )i; file. close (); catch ( Exception e ) gr. status = -1; gr.e = e; gr. count ++; if ( gr. count >= gr. buffer. length ) return gr; 13

/ l i s t dir contents @param name directory name/path @return l i s t of strings public String [] list ( String name ) throws RemoteException try File dir = new File ( cwd, name ); return dir. list (); catch ( Exception e ) System. out. println ( " Exception : " + e ); return null ; / t e s t f i l e existence of given f i l e @param name f i l e to t e s t @return true i f exists, f a l s e otherwise public boolean exists ( String name ) throws RemoteException File file = new File ( cwd, name ); return file. exists (); public FileServer () throws RemoteException super (); cwd = System. getproperty ( " user. dir " ); public static void main ( String args [] ) String hostname ; String name ; if ( System. getsecuritymanager () == null ) System. setsecuritymanager ( new RMISecurityManager () ); try hostname = InetAddress. getlocalhost (). gethostname (); catch ( java. net. UnknownHostException e ) hostname = " localhost "; name = "//" + hostname + "/ FileServer "; try FileServer fs = new FileServer (); Naming. rebind ( name, fs ); System. err. println ( " Server Launched." ); catch ( Exception e ) 14

System. err. println ( " ComputeEngine exception : " + e. getmessage () ); e. printstacktrace (); import java. io.*; import java. rmi.*; Listing 7: FileClient.java Implementação do Cliente. public class FileClient static int BLOCK_SIZE = 8000; FileServerInterface fs; public FileClient ( String host ) if ( System. getsecuritymanager () == null ) System. setsecuritymanager ( new RMISecurityManager () ); try String name = "//" + host + "/ FileServer "; fs = ( FileServerInterface ) Naming. lookup ( name ); catch ( Exception e ) System. err. println ( " Exception : " + e ); public void cred () while ( true ) try String cred = fs. cred (); System. out. println ( " CRED : " + cred ); catch ( RemoteException e ) System. err. println ( " Connection Error : " + e ); System. err. println ( " Trying Again... " ); public void getfile ( String src, String dst, boolean statistics ) long offset = 0; GetFileResult gr; FileOutputStream file ; long count = 0; long t0, t1, t2; try file = new FileOutputStream ( dst ); catch ( FileNotFoundException e ) System. err. println ( " ERROR : " + e ); return ; t0 = System. currenttimemillis (); while ( true ) 15

while ( true ) try t1 = System. currenttimemillis (); gr = fs. getfile ( src, offset, BLOCK_SIZE ); count += gr. count ; if ( statistics ) t2 = System. currenttimemillis (); System. out. println ( " STAT : Got " + gr. count + " bytes in "+ (t2 - t1 ) + " ms." ); catch ( RemoteException e ) System. err. println ( " Connection Error : " + e ); System. err. println ( " Trying Again... " ); if ( gr. status >= 0 ) offset += gr. buffer. length ; try file. write ( gr. buffer, 0, gr. count ); if ( gr. status == 0 ) catch ( IOException e ) System. err. println ( " ERROR : " + e ); System. err. println ( " ERROR : " + gr.e ); t2 = System. currenttimemillis (); String unity ; double rate ; if ( count > 1024 * 1024 ) count /= ( 1024 * 1024 ); unity = " Mb"; if ( count > 1024 ) count /= 1024; unity = " Kb"; unity = " b"; rate = ( float ) count * 1000.0 / ( t2 - t0 ); System. out. println ( " Got " + src + " " + count + unity + " in " + (t2 - t0 ) + "ms [" + rate + unity + "/s]" ); try 16

file. close (); catch ( IOException e ) System. err. println ( " ERROR : " + e ); public void list ( String name ) int i; String dir []; while ( true ) try dir = fs. list ( name ); catch ( RemoteException e ) System. err. println ( " Connection Error : " + e ); System. err. println ( " Trying Again... " ); if ( dir == null ) System. err. println ( " Could not list dir " + name + " " ); for ( i=0; i < dir. length ; i++ ) System. out. println ( dir [ i ] ); public void exists ( String name ) String result = new String (); boolean r; while ( true ) try r = fs. exists ( name ); catch ( RemoteException e ) System. err. println ( " Connection Error : " + e ); System. err. println ( " Trying Again... " ); result = " File " + name + " does "; if (! r ) result += " NOT "; result += " exist."; System. out. println ( result ); public static String getline () String inputline = ""; return inputline ; public static void main ( String [] args ) if ( args. length < 1 ) System. err. println ( " You must provide the server name!" ); return ; 17

FileClient fc = new FileClient ( args [ 0 ] ); BufferedReader in = new BufferedReader ( new InputStreamReader ( System. in ), 1 ); String line = ""; String a []; while ( true ) System. out. print ( " > " ); try line = in. readline (); catch ( IOException e ) System. err. println ( " Exception : " + e ); continue ; line. trim (); a = line. split ( " " ); if ( a. length < 1 ) continue ; if ( ( a [ 0 ]. compareto ( " quit " ) == 0 ) ( a [ 0 ]. compareto ( " exit " ) == 0 ) ) if ( a [ 0 ]. compareto ( " list " ) == 0 ) String dir = "."; if ( a. length > 1 ) dir = a [ 1 ]; fc. list ( dir ); if ( a [ 0 ]. compareto ( " exist " ) == 0 ) if ( a. length < 2 ) System. out. println ( " Filename required!" ); continue ; fc. exists ( a [ 1 ] ); if ( a [ 0 ]. compareto ( " get " ) == 0 ) String src ; String dst ; if ( a. length == 2 ) src = a [ 1 ]; dst = a [ 1 ]; if ( a. length > 2 ) src = a [ 1 ]; dst = a [ 2 ]; System. out. println (" Missing source filename!"); continue ; fc. getfile ( src, dst, false ); if ( a [ 0 ]. compareto ( " getstat " ) == 0 ) String src ; String dst ; if ( a. length == 2 ) 18

src = a [ 1 ]; dst = a [ 1 ]; if ( a. length > 2 ) src = a [ 1 ]; dst = a [ 2 ]; System. out. println (" Missing source filename!"); continue ; fc. getfile ( src, dst, true ); if ( a [ 0 ]. compareto ( " cred " ) == 0 ) fc. cred (); 19