Cuénteme acerca de un programa escrito en lenguaje C para implementar la transferencia de archivos utilizando el protocolo UDP.
Este programa ha sido compilado, ejecutado y probado bajo Windows 7 Visual Studio 2015 y Linux Ubuntu 15.04 GCC 5.11.
Este programa admite la transferencia de archivos entre Windows y Linux. Si desea transferir archivos entre Windows y Linux, los caracteres chinos no pueden aparecer en el nombre del archivo.
Este programa admite transceptores WiFi y USB inalámbricos, pero solo admite la transferencia de archivos dentro de la LAN. Para transferir archivos, debe ingresar la dirección IP de la otra parte.
Este programa incluye un lado del servidor y un lado del cliente, que pueden tanto enviar archivos como recibir archivos. Si desea realizar la prueba en la misma máquina, debe abrir ambos programas al mismo tiempo.
El comando para verificar la dirección IP de esta máquina en Windows es: ipconfig
El comando para verificar la dirección IP de esta máquina en Linux es: ifconfig
El siguiente es el código del programa: #includelt;stdio.hgt;
#includelt;stdlib.hgt;
#includelt;string.hgt;
#includelt;math.hgt;
#ifdef?_MSC_VER
#includelt;winsock2.hgt;
#includelt;windows.hgt;
#pragma?comment( lib,?"ws2_32.lib")
#else
#includelt;pthread.hgt;
#includelt; unistd.hgt;
#includelt;signal.hgt;
#includelt;sys/socket.hgt;
#includelt;arpa/inet.hgt;
# endif
//?Almacenar el tamaño de la matriz de caracteres de envío y recepción
#define?SIZEA?65501
/ /?El número de bytes enviados y recibidos cada vez
#define?SIZEB?65500
typedef?struct?sockaddr_in?SockAddrIn;
SockAddrIn?serverAddr, ?remoteAddr,?clientAddr;
/ /?Número de puerto
int?iServerPort,?iClientPort;
//?Nueva?información?socket
int?iUDP;
//?Convertir cadena a entero
int?strToInt(char*?acStr)
{
int?i, ?iIndex?=?0 ,?iNum?=?0,?iSize?=?0;
if(acStr[0]?==?' '?|| ?acStr[0]?==?'-')
iIndex?=?1;
for(iSize=iIndex;?;?iSize)
if(acStr[iSize]?lt;?'0 '?||?acStr[iSize]?gt;?'9')
romper;
for(i= iIndex;?ilt;iSize;?i)
iNum? =?(int)pow(10,?iSize?-?i?-?1)?*?(acStr[i]?-? 48);
if(acStr [0]?==?'-')
iNum?=?-?iNum;
return?iNum;
}
//?Convertir entero en cadena
void?intToStr(int?iInt, ?char*?acStr)
{
int?iIndex? =?0,?iSize,?iNum,?iBit,?i,?j;
if(iInt?lt;?0)
{
acStr[0]?=?'-';
iInt?=?-?iIn
t;
iIndex?=?1;
}
for(i=0;?;?i)
if( iInt?lt;?pow(10,?i))
romper;
iSize?=?i;
for(i=0;?ilt ;iSize;?i )
{
iNum?=?pow(10,?iSize?-?i?-?1);
iBit? =?iInt/iNum;
iInt?-=?iNum*iBit;
acStr[i?iIndex]?=?iBit?48;
}
if(iSize?=?0)
acStr[iSize?iIndex]?=?'\0';
else
p>{
acStr[0]?=?'0';
acStr[1]?=?'\0';
}
}
void?sleepUDP(int?iSleep)
{
#ifdef?_MSC_VER
Dormir(iSleep);
#else
usleep(iSleep*1000);
#endif
}
void?openUDP(char*?acIpAddr)
{
#ifdef?_MSC_VER
//?Winsows?Enable?socket
WSADATA?wsadata;
if(WSAStartup(MAKEWORD(1,?1),?amp;wsadata)?==?SOCKET_ERROR)
{
printf("¿Habilitar?socket?Error\n");
salir(0);
}
#endif
//?Nuevo?socket
if((iUDP?=?socket(AF_INET,?SOCK_DGRAM,?IPPROTO_UDP))?==?-1)
{
printf("¿Crear?socket?Error\n");
salir(0);
}
//?Borrar p> p>
memset(amp;serverAddr,?0,?sizeof(serverAddr));
memset(amp;clientAddr,?0,?sizeof(clientAddr));
//?Establecer protocolo?Dirección?IP?y?Puerto
serverAddr.sin_family?=?AF_INET;
serverAddr.sin_port?=?htons(iServerPort); p>
serverAddr.sin_addr.s_addr?=?htonl(INADDR_ANY);
clientAddr.sin_family?=?AF_INET;
clientAddr.sin_port?=?htons(iClientPort) ;
clientAddr.sin_addr.s_addr?=?inet_addr(acIpAddr);
///?Puerto de enlace, puerto de escucha
if(bind(iUDP,?(struct?sockaddr*)amp;serverAddr,?sizeof(serverAddr))?==?-1)
{
printf("Error en el enlace de puerto\n");
exit(0);
}
}
void?closeUDP(void)
{
#ifdef?_MSC_VER
//?Winsows?Close?socket p>
closesocket(iUDP);
WSACleanup();
#endif
}
//?Para enviar cadena
char?acSendStr[TAMAÑO];
//?cadena recibida
char?acRecvStr[TAMAÑO];
//?Request información
char?acReq[SIZEA];
//?Cadena de nombre de archivo
char?acFileName[SIZEA]
/ /?Cadena de número de bytes de archivo
char?acFileSize[SIZEA];
int?iSize,?iNameSize;
//?Recibir nombre de archivo
#ifdef?_MSC_VER
DWORD?WINAPI?recvName(LPVOID?p)
#else
void*?recvName(void*?arg )
#endif
{
int?iAddrSize?=?sizeof(remoteAddr);
acReq[0]?=? 'n';?acReq[1]?=?'a';?acReq[2]?=?'m';?acReq[3]?=?'e'; ?acReq[4]?=?'\ 0';
acRecvStr[0]?=?'\0';
printf("s\n",?" es ¡Enviar información de solicitud! ");
//?Enviar información de solicitud
sendto(iUDP,?acReq,?strlen(acReq),?0,?(struct?sockaddr*) amp; clientAddr,?sizeof(clientAddr)) ;
//?Esperar un período de tiempo después de enviar cada mensaje de solicitud
sleepUDP(10);
/ /?Recibir nombre de archivo p>
iSize?=?recvfrom(iUDP,?acRecvStr,?SIZEB,?0,?(struct?sockaddr*)amp;remoteAddr,?amp;iAddrSize);
return?0;
}
//?Recibir archivo
void?recvFile(char*?acDirName,?char*?acIpAddr)
{
FILE*?pFile?=?NULL;
int?i, ?iFileSize, ?iRecvNum, ?iAddrSize?=?sizeof(remoteAddr); //Nombre del archivo de ruta
char?acDirAndFileName[
TAMAÑOA];
openUDP(acIpAddr);
//?Recibir nombre de archivo
for(;;)
{ p>
//?Crear hilo
#ifdef?_MSC_VER
HANDLE?hThread;
DWORD?threadId;
hThread?=?CreateThread(NULL,?0,?recvName,?0,?0,?amp; threadId);
//?Esperar un período de tiempo después de cada envío
sleepUDP(1000);
//? Terminar con fuerza el hilo
TerminateThread(hThread,?0);
#else
pthread_t ?thread;
void*?thread_arg?=?(pthread_t)0;
pthread_create(amp;thread,?NULL,?recvName,?(void*)amp ;thread_arg) ;
//?Esperar un período de tiempo después de cada envío
sleepUDP(1000);
//?Forzar la terminación del hilo
pthread_cancel(thread);
#endif
if(acRecvStr[0]?=?'\0')
{
acRecvStr[iSize]?=?'\0';
printf("Nombre de archivo: s\n",?acRecvStr);
break;
}
}
acDirAndFileName[0]?=?'\0';
strcat(acDirAndFileName,?acDirName);
//?Conecte el nombre de la ruta y el nombre del archivo
strcat(acDirAndFileName,?acRecvStr);
//?Si el archivo ya existe, borre el archivo contenido
pFile?=?fopen(acDirAndFileName,?"w");
fclose(pFile);
acReq[0]?=?'s ';?acReq[1 ]?=?'i';?acReq[2]?=?'z';?acReq[3]?=?'e';?acReq[4]?=?'\0' ;
//?Recibir bytes de archivo
for(;;)
{
//?Enviar información de solicitud
sendto(iUDP,?acReq,?strlen(acReq)?1,?0,?(struct?sockaddr*)amp;clientAddr,?sizeof(clientAddr));
//? Enviar cada vez Espere un período de tiempo después de solicitar información
sleepUDP(10);
//?El número de bytes del archivo recibido
acRecvStr [0]?=?'\0 ';
iSize?=?recvfrom(iUDP,?acRecvStr,?SIZEB,?0,?(struct?sockaddr*)amp;remoteAddr,?amp;iAddrSize );
if(acRecvStr[0]?!=?'\0')
>{
acRecvStr[iSize]?=?'\0';
iFileSize?=?strToInt(acRecvStr);
printf("Bytes del archivo el número es: d\n",?iFileSize);
break;
}
}
//?En modo agregar Escribir en el archivo
pFile?=?fopen(acDirAndFileName,?"ab");
//?¿Cuántas veces se recibirá el archivo?
iRecvNum?=? iFileSize/SIZEB;
//?Recibir archivos
for(i=0;?ilt;iRecvNum;?i)
{
intToStr(i,?acReq);
for(;;)
{
//?Enviar información de la solicitud
sendto(iUDP,?acReq,?strlen(acReq)?1,?0,?(struct?sockaddr*)amp;clientAddr,?sizeof(clientAddr));
printf(" s\t Recibiendo la sección ?d? del archivo\n",?acReq,?i);
//?Espere un período de tiempo después de enviar cada mensaje de solicitud
sleepUDP(10) ;
//?Recibir un archivo
iSize?=?recvfrom(iUDP,?acRecvStr,?SIZEB,?0,?(struct?sockaddr* )&;remoteAddr,? amp;iAddrSize);
if(iSize?==?SIZEB)
{
//?Escribe el archivo en el anexo modo
fwrite(acRecvStr,?sizeof(char),?iSize,?pFile);
break;
}
}
}
//?Recibir los bytes restantes del archivo
iSize?=?iFileSizeSIZEB;
if(iSize?gt ;?0)
{
acReq[0]?=?'l';?acReq[1]?=?'a';?acReq[2]?=? 's';?acReq[3 ]?=?'t';?acReq[4]?=?'\0';
for(;;)
{
// ?Enviar información de solicitud
sendto(iUDP, ?acReq, ?strlen(acReq)? ?1, ?0, ?(struct?sockaddr*)amp; clientAddr, ? sizeof(clientAddr)); p>
//?Espere un período de tiempo después de enviar cada mensaje de solicitud
sleepUDP(10);
//? Reciba los bytes restantes del archivo
if(recvfrom(iUDP,?acRecvStr,?iSize,?0,?(struct?sockaddr*)amp;remoteAddr,?amp;iAddrSize)?==?iSize )
{
//?Escribir archivos en modo agregar
fwrite(acRecvStr,?sizeof(char),?iSize,?pFile); p>
romper;
}
}
}
printf("s\n",?"¡Recepción de archivo completada!");
//? Cerrar el archivo
fclose(pFile);
//?Cerrar la conexión
closeUDP();
}
//?Enviar nombre de archivo
#ifdef?_MSC_VER
DWORD?WINAPI?sendName(LPVOID?p)
#else
void*?sendName(void*?arg)
#endif
{
int?iAddrSize?=?sizeof(remoteAddr);
acRecvStr[0]?=?'\0';
//?Recibir solicitud
printf("s\n",?"Recibiendo información de solicitud ! ");
recvfrom(iUDP,?acRecvStr,?5,?0,?(struct?sockaddr*)amp;remoteAddr,?amp;iAddrSize);
// Esperar un período de tiempo después de recibir la información de cada solicitud
sleepUDP(10);
//? Si la información de la solicitud es correcta, envíe el nombre del archivo
if(acRecvStr[0 ]?==?'n'?amp;?acRecvStr[1]?==?'a'?amp;amp;?acRecvStr[2]?==?'m'?amp; amp;?acRecvStr[ 3]?==?'e'?amp;?acRecvStr[4]?==?'\0')
sendto(iUDP,?acFileName,?iNameSize,?0 ,?( struct?sockaddr*)amp; clientAddr,?sizeof(clientAddr));
return?0;
}
//?Enviar archivo
void?sendFile(char*?acDirAndFileName, ?char*?acIpAddr)
{
int?i, ?j, ?iFileSize, ?iSendNum, ?iAddrSize? =?sizeof(remoteAddr);
FILE*?pFile?=?NULL;
pFile?=?fopen(acDirAndFileName,?"rb");
fseek(pFile,?0,?SEEK_END);
//?Número de bytes de archivo
iFileSize?=?ftell(pFile);
intToStr (iFileSize,?acFileSize);
//printf("s\n",?acDirAndFileName);
//?Obtener la longitud del nombre del archivo
iSize ?=?strlen(acDirAndFileName);
for(i=iSize-1,?iNameSize=0;?igt;=0;?i--,iNameSize)
if( acDirAndFileName[i]?==?'\\'?||?acDirAndFileName[i]?==?'/')
romper;
// imprimir
f("d\n",?iNameSize);
//?Nombre del archivo de intercepción
for(i=0;?ilt;iNameSize;?i)
acFileName[i]?=?acDirAndFileName[iSize?-?iNameSize?i];
acFileName[iNameSize]?=?'\0';
// printf("s\n",?acFileName);
openUDP(acIpAddr);
//?Enviar nombre de archivo
for(;;)
{
//?Crear hilo
#ifdef?_MSC_VER
HANDLE?hThread;
DWORD? threadId;
hThread?=?CreateThread(NULL,?0,?sendName,?0,?0,?amp;threadId);
//?Recibir información de solicitud cada vez Luego espere un período de tiempo
sleepUDP(1000);
//? Finalice el hilo a la fuerza
TerminateThread(hThread,?0); p>
#else
pthread_t?thread;
void*?thread_arg?=?(pthread_t)0;
pthread_create(amp;thread, ?NULL,? sendName,?(void*)&thread_arg);
//?Espere un período de tiempo después de recibir cada mensaje de solicitud
sleepUDP(1000); p>
/// Terminar con fuerza el hilo
pthread_cancel(thread);
#endif
//?Salir del ciclo si se recibe la información solicitada. es correcto
if(acRecvStr[0]?==?'n'?amp; ?acRecvStr[1]?==?'a'?amp; ?acRecvStr[2]?==?' m'?amp; amp;?acRecvStr[3]?==?'e'?amp;amp;?acRecvStr[4]?==?'\0')
descanso;
}
//?Enviar bytes de archivo
for(;;)
{
acRecvStr[0]? =?' \0';
//?Recibir solicitud
recvfrom(iUDP,?acRecvStr,?5,?0,?(struct?sockaddr*)amp;remoteAddr, ?amp; iAddrSize);
//?Espere un período de tiempo después de recibir la información de cada solicitud
sleepUDP(10);
//? Si la información de la solicitud es correcta
p>
if(acRecvStr[0]?==?'s'?amp;amp;?acRecvStr[1]?==?'i'?amp ;amp;?acRecvStr[2]?==?' z'?amp;amp;?acRecvStr[3]?==?'e'?amp;amp;?acRecvStr[4]?==?'\0' )
{
//?Enviar bytes de archivo
sendto(iUDP,?acFileSize,?strlen(a
cFileSize),?0,?(struct?sockaddr*)amp; clientAddr,?sizeof(clientAddr));
break;
}
}
iSendNum?=?iFileSize/SIZEB;
//?Enviar archivo
if(iSendNum?gt;?0)
{
for(i=0;;i)
{
acRecvStr[0]?=?'\0';
//Recibir solicitud
recvfrom(iUDP,?acRecvStr,?SIZEB,?0,?(struct?sockaddr*)amp;remoteAddr,?amp;iAddrSize);
printf ("s\está enviando la sección ?d? del archivo\n",?acRecvStr,?i);
//?Espere un período de tiempo después de recibir cada mensaje de solicitud
sleepUDP(10);
fseek(pFile,?strToInt(acRecvStr)*SIZEB,?SEEK_SET);
fread(acSendStr,?1,?SIZEB,? pFile);
//printf("s\n",?acSendStr);
//?Enviar un archivo
sendto(iUDP,?acSendStr) ,?SIZEB ,?0,?(struct?sockaddr*)amp;clientAddr,?sizeof(clientAddr));
if(strToInt(acRecvStr)?gt;=?iSendNum?-?1)
break;
}
}
//?Enviar los bytes restantes del archivo
iSize? =?iFileSizeSIZEB;
if(iSize?gt;?0)
{
for(;;)
{ p>
acRecvStr[0]?=?'\0';
//?Recibir solicitud
recvfrom(iUDP,?acRecvStr,?5,?0,? (struct?sockaddr* )amp;remoteAddr,?amp;iAddrSize);
//?Espere un período de tiempo después de recibir la información de cada solicitud
sleepUDP(10);
/ /?Si la información solicitada es correcta
if(acRecvStr[0]?==?'l'?amp;amp;?acRecvStr[1]?==? 'a'?amp;amp;?acRecvStr [2]?==?'s'?amp;amp;?acRecvStr[3]?==?'t'?amp;amp;?acRecvStr[4]?== ?'\0')
{
fseek(pFile,?iSendNum*SIZEB,?SEEK_SET);
fread(acSendStr,?1,?iSize ,?pFile);
//printf("s\n",?acSendStr);
//?Enviar los bytes restantes del archivo
enviar a (iUDP,?acSendStr,?iSize,?0,?(struct?sockaddr*)a
mp; clientAddr,?sizeof(clientAddr));
romper;
}
}
}
printf("s\n",?"¡Archivo enviado!");
//?Cerrar la conexión
closeUDP();
}
int?main(void)
{
char?acDirName[TAMAÑO];
char?acDirAndFileName[TAMAÑO]; p>
p>
char?acIpAddr[15];
int?i, ?iOption?=?0, ?iSize?=?0;
ARCHIVO *?pFile?= ?NULL;
char?cLast?=?'\\';
opción:
printf("s\n", ?"*** ********************************************** ****\ nEste programa incluye un lado del servidor y un lado del cliente, que pueden enviar y recibir archivos. \nAdmite transceptores inalámbricos WiFi y USB, pero solo admite la transferencia de archivos dentro de la LAN. \nSi desea utilizar Windows y Windows. Al transferir archivos entre Linux y Linux, los caracteres chinos no pueden aparecer en el nombre del archivo. \nSi desea realizar la prueba en la misma máquina, debe abrir dos programas al mismo tiempo. ********. **********************************");
printf("s\ n",?"Ingrese las opciones, 1. Enviar archivos, 2. Recibir archivos ");
scanf("d",?amp; iOption);
// ?Enviar archivo
if(iOption?==?1)
{
iServerPort?=?1025;
iClientPort?= ?1024;
nombre de archivo:
printf("s\n",?"Ingrese el nombre del archivo de ruta que se enviará.\nWindows ? Formato del nombre del archivo de ruta:\t\tC :\\install.txt\nLinux? Formato del nombre del archivo de ruta: \t\t/home/install.txt");
scanf("s", ?acDirAndFileName);
pFile?=?fopen(acDirAndFileName,?"rb");
if(pFile?==?NULL)
{
printf("s \n",?"Error al leer el archivo, vuelva a ingresar el nombre del archivo. ");
goto?fileName;
}
//?Cerrar el archivo
fclose(pFile);
printf("s\n",?"Ingrese la dirección IP de la parte que recibe el archivo sin espacios.
\nPor ejemplo:\n192.168.1.104");
scanf("s",?acIpAddr);
sendFile(acDirAndFileName,?acIpAddr);
}
//?Recibir archivos
else?if(iOption?==?2)
{
iServerPort? =?1024;
iClientPort?=?1025;
dirName:
printf("s\n",?"Ingrese el nombre de la ruta para guardar el archivo .\nWindows?Formato de nombre de ruta:\t\tC:\\img\\\nLinux?Formato de nombre de ruta:\t\t/home/");
scanf("s",?acDirName );
iSize?=?strlen(acDirName);
//?Compruebe si es un nombre de ruta de Linux
for(i=0;? ilt;iSize;?i )
{
if(acDirName[i]?==?'/')
{
cLast?=?'/';
break;
}
}
//?Comprueba el último carácter del nombre de ruta ¿Es?\?o?/
if(acDirName[iSize?-?1]?=?cLast)
{
acDirName[iSize ] ?=?cLast;
acDirName[iSize? ?1]?=?'\0';
}
acDirAndFileName[0]?=? ' \0';
strcat(acDirAndFileName,?acDirName);
strcat(acDirAndFileName,?"a.txt");
//?Trial guardar un archivo insignificante
pFile?=?fopen(acDirAndFileName,?"w");
if(pFile?==?NULL)
{
printf("s\n","El archivo no se puede crear en esta ruta, vuelva a ingresar el nombre de la ruta.");
goto?dirName;
}
else
{
//?Cerrar el archivo
fclose(pFile);
// ?Eliminar archivo
remove(acDirAndFileName);
}
printf("s\n",?"Ingrese la dirección IP de la parte que envía el archivo, no puede haber espacios. \nPor ejemplo:\n192.168.2.249");
scanf("s",?acIpAddr);
recvFile(acDirName,?acIpAddr);
}
else
{
printf("s\n",?"No existe tal opción, vuelva a ingresar.");
ir a?opción;
}
regresar?0;
}