Al final lo tengo casi resuelto aunque me queda un problema. Si el fichero es pequeño y lo envío en un solo paquete todo va bien, pero si lo envío a trozos porque es más grande que el tamaño del buffer, no me llega el archivo entero al servidor, y además llega con símbolos raros
. Los estoy leyendo correctamente, pero se pierden paquetes en el envío por lo que no debo estar enviando la información correctamente por el socket.
De hecho, he comprobado que solo llega "bien" el primer paquete, los siguientes llegan con símbolos raros:
Código C:
Ver original#pragma comment(lib, "wsock32.lib")
#include <stdio.h>
#include <windows.h>
#include <Winsock.h>
WSADATA ws;
char buf[10000];
void output(char *str)
{
FILE
*fp
= fopen("output.txt", "a+");}
SOCKET Connect(char* ftpname, int port)
{
WSAStartup(0x101, &ws);
// Open up a socket for out TCP/IP session
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
// Set up socket information.
struct sockaddr_in a = {AF_INET, htons(port)};
// Get the ip address of our ftp
struct hostent *h = gethostbyname(ftpname);
a.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *)h->h_addr)));
// Actually connect to the server
connect(s, (struct sockaddr *)&a, sizeof(a));
return s;
}
void receiving(SOCKET s, char* string)
{
char aa[1000] = {'/0'};
int ii = recv(s, aa, sizeof(aa), 0);
output(buf);
if(string !=0)
}
void sending(SOCKET s, char* verb)
{
output("Sending: ");
output(buf);
}
int _stdcall WinMain(HINSTANCE i, HINSTANCE j, char* k, int l)
{
//Creacion de socket para conectar con FTP
SOCKET s1 = Connect("ftp.xxxxxxxxxxxxxxx.com", 21);
receiving(s1,0);
//Envio de usuario
sending(s1, "USER xxxxxxx");
receiving(s1,0);
//Envio de contraseña
sending(s1, "PASS yyyyyyyyyy");
receiving(s1,0);
//Envio de tipo de archivos que aceptará, en este caso binarios
sending(s1, "TYPE I");
receiving(s1, 0);
char strPasv[1000];
//Enviamos la activación del modo pasivo
sending(s1, "PASV");
receiving(s1, strPasv);
//Parseamos para quedarnos exclusivamente con la IP y el puerto
int cont=0;
int hostFound=0;
int salida=0;
char ipHost[24]="";
while((cont<sizeof(strPasv))&&(!salida))
{
if(strPasv[cont]=='(')
{
hostFound=1;
}
else if(strPasv[cont]==')')
{
salida=1;
}
else if(hostFound)
{
sprintf(ipHost
,"%s%c",ipHost
,strPasv
[cont
]); }
cont++;
}
char *trozos;
//Separamos los trozos por las comas
//Por cada trozo leido, la introduciremos en su correspondiente variable
char ipFTP2[16]="";
int hp=0;
int lp=0;
for(i=0;trozos;i++)
{
//Almacenamos cada trozo en la IP
if(i<16)
{
if(i==0)
{
sprintf(ipFTP2
,"%s%s",ipFTP2
,trozos
); }
else
{
sprintf(ipFTP2
,"%s.%s",ipFTP2
,trozos
); }
}
//Almacenamos el último trozo en el puerto
else if(i>=16)
{
if(i==16)
{
}
else
{
}
}
}
int portFTP2 = (hp*256) + lp;
printf("IP: %s - PASSIVE PORT: %d\n", ipFTP2
, portFTP2
); //Fin del parseador
//Enviamos STOR para crear el fichero en el FTP y comenzar el envio por el socket s2
char strS1[1000];
sending(s1, "STOR c.txt");
//Creamos segundo socket para conectar a la IP y PUERTO brindados por el server para el envio
SOCKET s2 = Connect(ipFTP2, portFTP2);
//Lectura de archivo en modo binario
char buf1[512]="";
int total=0;
FILE *pFichero;
pFichero
=fopen("c.txt", "rb"); {
int bytesR
= fread (buf1
, sizeof(char), sizeof(buf1
), pFichero
); break;
}
total+=bytesR;
send
(s2
, buf1
, strlen(buf1
), 0); }
printf("Total de bytes enviados: %d\n",total
);
//Cierro socket 2
sending(s2, "QUIT");
//Cierro socket 1
sending(s1, "QUIT");
receiving(s1,0);
return 0;
}
Hay que enviar algún tipo de flag o similar en los paquetes, o codificar en b64 durante el envío del contenido del archivo leído?
Graciass