Red de conocimiento informático - Programación de la red - Cuénteme acerca de un programa escrito en lenguaje C para implementar la transferencia de archivos utilizando el protocolo UDP.

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>

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);

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

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

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(;;)

{

//?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));

//?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);

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);

#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);

/// 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(;;)

{

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>

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;

}