Ir ao conteúdo

Cliente/Servidor FTP em C/C++


leitaoo

Posts recomendados

Postado

Estou necessitando para realização de um trabalho na faculdade desenvolver um “Serviço Internet” de transferência de arquivo FTP. E qualquer ajuda que puderem em dar eu ficaria muito grato. Qulaquer rotina... qualquer coisa.. precido de uma luz..

Muito Obrigado

Funcionalidade Básica:

O serviço deve prever o seguinte:

a) Projeto detalhado do protocolo, que deve ser textual, para comandos e respostas de

status, incluindo mensagens de erro, e que se utilizará do protocolo UDP para

transporte na rede;

B) As transferências de arquivo, para download ou upload, serão sempre em modo

binário, ou seja, ignorando totalmente o tipo de conteúdo dos arquivos;

c) Um Servidor FTP, capaz de responder às solicitações de um cliente FTP;

d) Um Cliente FTP, capaz de se conectar ao servidor e enviar comandos, conforme

descrito no item seguinte;

e) Conjunto mínimo de comandos:

• apaga nomearq – apaga o arquivo especificado por nomearq no diretório de

trabalho atual do servidor;

• baixe nomearq – solicita o envio (download) do arquivo especificado por

nomearq, contido na pasta de trabalho atual do servidor;

• dir – exibe o conteúdo (lista) do diretório de trabalho atual no servidor;

• fecha – encerra a sessão com o servidor;

• idt – identificar diretório de trabalho atual no servidor;

• mdlt nomedir – muda o diretório local de trabalho do cliente para o diretório

especificado em nomedir;

• mdt nomedir – muda o diretório de trabalho do servidor para o diretório

especificado em nomedir;

• suba nomearq – solicita a recepção (upload) do arquivo local especificado por

nomearq para o diretório de trabalho atual no servidor;

Nota: a especificação de diretórios (nomedir) no servidor e no cliente serão sempre com

relação a um diretório raiz, que será especificado quando o programa é executado.

Recursos:

Para a consecução destes objetivos deve-se valer de rotinas e/ou bibliotecas

de funções disponíveis na Internet, mas não programas completos.

O desenvolvimento do sistema deverá ser realizado exclusivamente em ambiente Windows,

em linguagem C, C++ ou FreePASCAL, compilável no ambiente Dev-Cpp ou Dev-Pascal, da

Bloodshed.

Tenho alguns modelos q me falaram q podem ajudar.... mas até agora sem luz...


//
// DServer.cpp
//
// Programa extremamente simples, como exemple de um cliente modo datagrama
// totalmente inútil.
// Opera em conjunto com DClient.cpp.
//
// O programa se instala como um servidor utilizando o protocolo UDP.
// Ele aguarda dados vindos de um cliente, apresenta os dados recebidos,
// envia uma mensagem de volta para o cliente e aguarda nova mendagem.
//
// Compile e link com wsock32.lib
//
// Forneça o número da porta de serviço na qual o servidor deve aguardar
// uma conexão na linha de comando
// Qualquer porta que não esteja em uso no sistema pode ser especificada
//
// Exemplo: DServer 2000
//
// Original em [url="http://www.sockaddr.com/ExampleSourceCode.html"]http://www.sockaddr.com/ExampleSourceCode.html[/url],
// arquivo "DataGram.zip"
//

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <winsock.h>

// Protótipo de função - função servidor
void DatagramServer(short nPort);

// Macro de auxílio para apresentar mensagens de erro
#define PRINTERROR(s) \
fprintf(stderr,"\n%: %d\n", s, WSAGetLastError())

////////////////////////////////////////////////////////////

int main(int argc, char *argv[])
{
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
int nRet;
short nPort;

//
// Verifique o parâmetro "porta" passado na linha de comando
//
if (argc != 2)
{
fprintf(stderr,"\nSyntax: dserver PortNumber\n");
exit(1);
}

nPort = atoi(argv[1]);

//
// Inicializae o WinSock e verifique a versão
//
nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\n Wrong version\n");
exit(2);
}

//
// Assuma a função de servidor datagrama
//
DatagramServer(nPort);

//
// Libere o WinSock (NOTA: em operação normal, o servidor nunca chega aqui!)
//
WSACleanup();
}

////////////////////////////////////////////////////////////

void DatagramServer(short nPort)
{
time_t seconds;
struct tm *timeinfo;
//
// Crie um socket tipo dagrama UDP/IP
//
SOCKET theSocket;

theSocket = socket(AF_INET, // Família de endereço ("Internet")
SOCK_DGRAM, // Tipo de Socket
IPPROTO_UDP); // Protocolo
if (theSocket == INVALID_SOCKET)
{
PRINTERROR("socket()");
return;
}


//
// Preencha a estrutura de endereço
//
SOCKADDR_IN saServer;

saServer.sin_family = AF_INET;
saServer.sin_addr.s_addr = INADDR_ANY; // WinSock escolherá o endereço
saServer.sin_port = htons(nPort); // Use a porta passada pelo usuário

//
// associe nome ao socket
//
int nRet;

nRet = bind(theSocket, // Descritor do Socket
(LPSOCKADDR)&saServer, // Endereço de associação
sizeof(struct sockaddr) // Tamanho do endereço
);
if (nRet == SOCKET_ERROR)
{
PRINTERROR("bind()");
closesocket(theSocket);
return;
}

//
// Normalmente isto não é requerido, mas aqui o servidor apresenta seu nome
// e a porta onde aguarda uma conexão do cliente, para ser utilizado
// com o programa cliente.
//
int nLen;
nLen = sizeof(SOCKADDR);
char szBuf[256];

nRet = gethostname(szBuf, sizeof(szBuf));
if (nRet == SOCKET_ERROR)
{
PRINTERROR("gethostname()");
closesocket(theSocket);
return;
}

//
// Mostre o nome do seervidor e o número da porta
//
printf("\nServer named %s waiting on port %d\n",
szBuf, nPort);

//
// Aguarde chegar um datagrama de um cliente
//
SOCKADDR_IN saClient;

while(1) // Este ciclo é "eterno", isto é um servidor!
{
memset(szBuf, 0, sizeof(szBuf)); // limpe o buffer de trabalho
// aguarde chegar dados de um cliente
nRet = recvfrom(theSocket, // associe o socket
szBuf, // Buffer de recepção
sizeof(szBuf), // Tamanho do buffer em bytes
0, // Flags
(LPSOCKADDR)&saClient, // Buffer para receber endereço do cliente
&nLen); // Tamanho do buffer

char *client;
client = inet_ntoa(saClient.sin_addr);

//
// Mostre que foram recebidos dados de um cliente
//
printf("\nData received %s %s:%d",szBuf,client,ntohs(saClient.sin_port));

//
// Envie resposta ao cliente
//
time(&seconds);
timeinfo = localtime(&seconds);

memset(szBuf, 0, sizeof(szBuf));

strcpy(szBuf," at ");
strcat(szBuf,asctime(timeinfo));
strcat(szBuf, " from Server");
sendto(theSocket, // Associe socket
szBuf, // Buffer de transmissão
strlen(szBuf), // Comprimento dos dados a serem enviados
0, // Flags
(LPSOCKADDR)&saClient, // Endereço de destino (cliente)
nLen); // Comprimento do endereço

//
// Normalmente um servidor continua a executar,
// ficando disponível para outros clientes.
//
}
closesocket(theSocket);
return;
}


CLIENTE


//
// DClient.cpp
//
// Programa extremamente simples como exemplo de um cliente "datagrama"
// totalmente inútil.
// Opera em conjunto com DServer.cpp.
//
// O programa tenta se conectar ao servidor e porta especificados na linha de
// de comanto. O programa DServer mostra as informações necessárias quando
// executado. Uma vez conectado, o programa envia dados para o servidor,
// aguarda uma resposta e então termina, apresentando uma mensagem com as
// informações recebidas.
//
// Compile e link com wsock32.lib.
//
// Passe o nome do servidor (ou endereço IP) e número da porta de serviço na
// linha de comando.
//
// Example: DClient MyMachineName 2000
//
// Original em [url="http://www.sockaddr.com/ExampleSourceCode.html"]http://www.sockaddr.com/ExampleSourceCode.html[/url],
// arquivo "DataGram.zip"
//

#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>

// Protótipo de Função - executa a função cliente
void DatagramClient(char *szServer, short nPort);

// Macro de auxílio para apresentar mensagens de erro
#define PRINTERROR(s) \
fprintf(stderr,"\n%: %d\n", s, WSAGetLastError())

//

int main(int argc, char *argv[])
{
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
int nRet;
short nPort;

//
// Verifique os argumentos passados na linha de comando
//
if (argc != 3)
{
fprintf(stderr,"\nSyntax: dclient ServerName PortNumber\n");
exit(1);
}

nPort = atoi(argv[2]);

//
// Inicialize o WinSock e verifique a versão
//
nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
fprintf(stderr,"\n Wrong version\n");
exit(2);
}

//
// Chame a função "cliente"
//
DatagramClient(argv[1], nPort);

//
// Libere o WinSock e termine
//
WSACleanup();
}

////////////////////////////////////////////////////////////

void DatagramClient(char *szServer, short nPort)
{

printf("\nDatagram Client sending to server: %s on port: %d\n",
szServer, nPort);

//
// Encontre o servidor
//
LPHOSTENT lpHostEntry; // estrutura que define um Host

lpHostEntry = gethostbyname(szServer);
if (lpHostEntry == NULL)
{
PRINTERROR("gethostbyname()");
return;
}


//
// Crie um socket para datagrama UDP/IP
//
SOCKET theSocket;

theSocket = socket(AF_INET, // Address family
SOCK_DGRAM, // Socket type
IPPROTO_UDP); // Protocol
if (theSocket == INVALID_SOCKET)
{
PRINTERROR("socket()");
return;
}

//
// Preencha a estrutura de endereçamento para o servidor
//
SOCKADDR_IN saServer;

saServer.sin_family = AF_INET; // Modelo "Internet"
saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list); // Endereço do servidor
saServer.sin_port = htons(nPort); // Porta de serviço obtido da linha de comando

//
// Envie dados para o servidor
//
char szBuf[256]; // Buffer para conter os dados
int nRet;

strcpy(szBuf, "from Client"); // preencha buffer com mensagem ...
// ... e envie
nRet = sendto(theSocket, // Socket
szBuf, // Data buffer
strlen(szBuf), // Length of data
0, // Flags
(LPSOCKADDR)&saServer, // Server address
sizeof(struct sockaddr)); // Length of address
// verifique se houve erro e retorne em caso afirmativo
if (nRet == SOCKET_ERROR)
{
PRINTERROR("sendto()");
closesocket(theSocket);
return;
}

//
// Aguarde uma resposta
//
// limpe o buufer para recepção dos dados
memset(szBuf, 0, sizeof(szBuf));
int nFromLen;

nFromLen = sizeof(struct sockaddr);
// Aguarde chegar o datagrama
recvfrom(theSocket, // Socket
szBuf, // Receive buffer
sizeof(szBuf), // Length of receive buffer
0, // Flags
(LPSOCKADDR)&saServer, // Buffer to receive sender's address
&nFromLen); // Length of address buffer

// Verifique se houve erro e retorne caso afirmativo
if (nRet == SOCKET_ERROR)
{
PRINTERROR("recvfrom()");
closesocket(theSocket);
return;
}

char *server;
server = inet_ntoa(saServer.sin_addr); // Obtenha o endereço IP do servidor

//
// Apresente os dados recebidos
//

printf("Data received %s %s:%d\n",szBuf,server,ntohs(saServer.sin_port));

// Feche o socket utilizado e retorne
closesocket(theSocket);
return;
}


  • 6 anos depois...
Postado

Como aprendizado em programação voltada para redes eu estou desenvolvendo um servidor FTP escrito em C/C++, em ambiente windows. Segue link com o código do Servidor FTP:

http://pastebin.com/2a5FRbpr

Eu testei o acesso ao servidor criado através do navegador (uso o Google Chrome), e ta funcionando legal.

Eu utilizo o DEV C++ como IDE, lembrando que para compilar tem que criar um projeto, adicionar o código e incluir a biblioteca libws2_32, biblioteca voltada para o uso de winsockets (no google é fácil encontrar tutoriais ensinando a linkar bibliotecas nos mais diversos IDEs).

Se alguém se interessar no assunto e quiser dar continuidade ao desenvolvimento, ou dicas de como melhorar o código, eu seria muito grato! valeu pessoal!

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...