====== Cliente e Servidor TFTP ======
O //Trivial File Transfer Protocol// (ou apenas TFTP) é um protocolo de transferência de arquivos, muito simples, semelhante ao [[FTP]].
O TFTP é usualmente utilizado para transferir pequenos arquivos entre //hosts// numa rede. O TFPT trabalha com o protocolo de transporte [[UDP]], o servidor TFTP recebe conexões na porta 69 e o tamanho de cada bloco é de 512 bytes.
Os exemplos abaixo trabalham na porta 2424 e o bloco tem tamanho de 1024 bytes.
===== Servidor TFTP simples =====
Recebe conexões (trata apenas 1 conexão por vez) e cria arquivo com permissão fixa. Neste Exemplo falta:
* Enviar mensagem de erro em caso de problemas
* Respeitar os atributos originais do arquivo
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SIZE_BUFFER 1024
int main(void)
{
int iSock, iFileDescriptor;
struct sockaddr_in my_addr;
struct sockaddr_in client_addr;
socklen_t addr_len;
int iNumBytes;
char sBuffer[SIZE_BUFFER];
if ((iSock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(2424);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero), 8);
if (bind(iSock, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) < 0 )
{
perror("bind");
exit(1);
}
/* loop infinito recebendo dados */
while(1)
{
addr_len = sizeof(struct sockaddr);
if ((iNumBytes=recvfrom(iSock, sBuffer, SIZE_BUFFER, 0, (struct sockaddr *)&client_addr, &addr_len)) < 0)
{
perror("recvfrom");
exit(1);
}
fprintf(stderr, "Recebendo pacotes de %s\n",inet_ntoa(client_addr.sin_addr));
fprintf(stderr, "o pacote tem %d bytes\n",iNumBytes);
sBuffer[iNumBytes] = '\0';
if( strcmp(sBuffer,"01INICIO") == 0 )
{
if ((iNumBytes=recvfrom(iSock, sBuffer, SIZE_BUFFER, 0, (struct sockaddr *)&client_addr, &addr_len)) < 0)
{
perror("recvfrom");
exit(1);
}
sBuffer[iNumBytes] = '\0';
fprintf(stderr, "\nRecebendo o arquivo %s", sBuffer);
iFileDescriptor = creat(sBuffer, 0644 ); /* permissao -rw-r--r-- */
if( iFileDescriptor < 0 )
{
perror("creat");
exit(1);
}
/* até todo o arquivo chegar, fico lendo */
iNumBytes=recvfrom(iSock, sBuffer, SIZE_BUFFER, 0, (struct sockaddr *)&client_addr, &addr_len);
while( iNumBytes > 0)
{
sBuffer[iNumBytes] = '\0';
if( strcmp(sBuffer, "01FIM") == 0) /* fim de transmissao */
{
break;
}
fprintf(stderr, "\nRecebendo ....... %d OK", iNumBytes);
write( iFileDescriptor, sBuffer, iNumBytes);
iNumBytes=recvfrom(iSock, sBuffer, SIZE_BUFFER, 0, (struct sockaddr *)&client_addr, &addr_len);
}
if( iNumBytes < 0 )
{
perror("recvfrom");
exit(1);
}
close(iFileDescriptor);
fprintf(stderr, "\nFim da transferencia");
}
}
close(iSock);
return 0;
}
===== Cliente TFTP Simples =====
Envia um arquivo a partir da linha comando. Neste exemplo falta:
* Notificar servidor no caso de erro
* Fazer autenticação junto ao servidor
* Enviar múltiplos arquivos
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SIZE_BUFFER 1024
int main(int argc, char *argv[])
{
int iSock, iFileDescriptor, iNumBytes;
struct sockaddr_in server_addr;
struct hostent *he;
char sBuffer[SIZE_BUFFER];
if (argc != 3)
{
printf("Passe o nome do servidor e o nome do arquivo a ser enviado");
exit(1);
}
/* convertendo o endereco passado para uma estrutura que eu entendo */
if ((he=gethostbyname(argv[1])) == NULL)
{
perror("gethostbyname");
exit(1);
}
if ((iSock = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
{
perror("socket");
exit(1);
}
/* abrir o arquivo passado */
iFileDescriptor = open(argv[2],O_RDONLY);
if( iFileDescriptor < 0 )
{
perror("open");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(2424); /* em homenagem a voces... ;) */
server_addr.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(server_addr.sin_zero), 8);
/* inicio do envio */
iNumBytes = sendto(iSock, "01INICIO", 8, 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if(iNumBytes < 0 )
{
perror("sendto");
exit(1);
}
/* primeiro é enviado o nome do arquivo */
iNumBytes = sendto(iSock, argv[2], strlen(argv[2]), 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if(iNumBytes < 0 )
{
perror("sendto");
exit(1);
}
iNumBytes = read(iFileDescriptor, &sBuffer, SIZE_BUFFER ) ;
while( iNumBytes > 0 )
{
/* enviando o buffer */
iNumBytes = sendto(iSock, sBuffer, iNumBytes, 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if(iNumBytes < 0 )
{
perror("sendto (2)");
exit(1);
}
fprintf(stderr, "\nEnviando ......................... %d OK", iNumBytes);
iNumBytes = read(iFileDescriptor, &sBuffer, SIZE_BUFFER ) ;
}
if( iNumBytes < 0 )
{
perror("read");
exit(1);
}
/* fim do envio */
iNumBytes = sendto(iSock, "01FIM", 5, 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if(iNumBytes < 0 )
{
perror("sendto");
exit(1);
}
close(iSock);
close(iFileDescriptor);
return 0;
}
--- //[[marcos@laureano.eti.br|Marcos Laureano]] 2008/04/29 09:11//