请教用C语言编的借助UDP协议实现的文件传输的程序
答案:2 悬赏:50 手机版
解决时间 2021-11-28 06:08
- 提问者网友:放下
- 2021-11-27 23:58
请教用C语言编的借助UDP协议实现的文件传输的程序
最佳答案
- 五星知识达人网友:北方的南先生
- 2021-11-28 00:41
本程序在 Windows 和 Linux 均编译通过
Windows VC 编译命令:cl -EHsc main.c
Windows MINGW 编译命令:gcc main.c -o main.exe -l ws2_32
Linux GCC 编译命令:gcc main.c -o main -l m
在 Linux 下编译需要把 #define MINGW32 这一行注释掉
#include
#include
#include
#include
#define MINGW32
#ifdef MINGW32
#include
#include
#pragma comment(lib, "ws2_32.lib")
#else
#include
#include
#include
#endif
struct sockaddr_in serverAddr, clientAddr, remoteAddr;
int strToInt(char* acStr)
{
int i, iIndex = 0, iNum = 0, iSize = strlen(acStr);
if(acStr[0] < '0' || acStr[0] > '9')
iIndex = 1;
for(i=iIndex; i iNum += (int)pow(10, iSize - i - 1) * (acStr[i] - 48);
if(acStr[0] == '-')
iNum = - iNum;
return iNum;
}
void intToStr(int iInt, char* acStr)
{
int iIndex = 0, iSize, iNum, iBit, i, j;
if(iInt < 0)
{
acStr[0] = '-';
iInt = - iInt;
iIndex = 1;
}
for(i=0; ; i++)
if(iInt < pow(10, i))
break;
iSize = i;
for(i=0; i {
iNum = pow(10, iSize - i - 1);
iBit = iInt/iNum;
iInt -= iNum*iBit;
acStr[i + iIndex] = iBit + 48;
}
if(iSize != 0)
acStr[iSize + iIndex] = '';
else
{
acStr[0] = '0';
acStr[1] = '';
}
}
int serverUDP(void)
{
int iRet, iServerFD;
#ifdef MINGW32
// Winsows 启用 socket
WSADATA wsadata;
if(WSAStartup(MAKEWORd(1, 1), &wsadata) == SOCKET_ERROR)
{
printf("启用 socket 失败
");
return 0;
}
#endif
// 新建 socket
if((iServerFD = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("新建 socket 失败
");
return 0;
}
// 清零
memset(&serverAddr, 0, sizeof(serverAddr));
// 设置协议
serverAddr.sin_family = AF_INET;
// 设置 IP
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
// 设置 Port
serverAddr.sin_port = htons(1024);
// 绑定端口,监听 1024 端口的任何请求
iRet = bind(iServerFD, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(iRet == -1)
{
printf("绑定端口失败
");
return 0;
}
return iServerFD;
}
int clientUDP(char* acIpAddr)
{
int iClientFD;
#ifdef MINGW32
//Winsows下启用socket
WSADATA wsadata;
if(WSAStartup(MAKEWORd(1, 1), &wsadata) == SOCKET_ERROR)
{
printf("启用 socket 失败
");
return 0;
}
#endif
// 新建 socket
if((iClientFD = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("新建 socket 失败
");
return 0;
}
// 设置协议及Port
memset(&serverAddr, 0, sizeof(serverAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons(1024);
// 设置需要连接的服务器 IP
clientAddr.sin_addr.s_addr = inet_addr(acIpAddr);
return iClientFD;
}
void closeUDP(int iSocketFD)
{
#ifdef MINGW32
// Winsows 关闭 socket
closesocket(iSocketFD);
WSACleanup();
#endif
}
void recvFile(char* acDirName)
{
int iServerFD = serverUDP();
int iSize = sizeof(remoteAddr);
int iFileSize, iByteNum, iNum;
char acFileName[255];
char acDirAndFileName[255];
char acStr[255];
// 获取文件名
iByteNum = recvfrom(iServerFD, acFileName, 255, 0, (struct sockaddr*)&remoteAddr, &iSize);
acFileName[iByteNum] = '';
printf("文件名为:%s
", acFileName);
// 连接路径名和文件名
strcat(acDirName, acFileName);
// 获取文件字节数
iByteNum = recvfrom(iServerFD, acStr, 255, 0, (struct sockaddr*)&remoteAddr, &iSize);
acStr[iByteNum] = '';
iFileSize = strToInt(acStr);
printf("文件字节数为:%d
", iFileSize);
FILE* pFile = fopen(acDirName, "ab");
int i;
if(iFileSize%255 == 0)
iNum = iFileSize/255;
else
iNum = iFileSize/255 + 1;
for(i=0; i {
iByteNum = recvfrom(iServerFD, acStr, 255, 0, (struct sockaddr*)&remoteAddr, &iSize);
fwrite(acStr, sizeof(char), iByteNum, pFile);
}
fclose(pFile);
closeUDP(iServerFD);
}
void sendFile(char* acDirAndFileName, char* acIpAddr)
{
int iClientFD, iByteNum, iNum, iSize, i, j;
char acFileName[1024];
char acFileByteNum[1024];
char acStr[256];
FILE* pFile = NULL;
pFile = fopen(acDirAndFileName, "rb");
// 文件字节数
fseek(pFile, 0, SEEK_END);
iByteNum = ftell(pFile);
intToStr(iByteNum, acFileByteNum);
//printf("%s
", acDirAndFileName);
// 获取文件名长度
iSize = strlen(acDirAndFileName);
for(i=iSize-1, iNum=0; i>=0; i--,iNum++)
if(acDirAndFileName[i] == '\' || acDirAndFileName[i] == '/')
break;
//printf("%d
", iNum);
// 截取文件名
for(i=0; i acFileName[i] = acDirAndFileName[iSize - iNum + i];
acFileName[iNum] = '';
//printf("%s
", acFileName);
iClientFD = clientUDP(acIpAddr);
// 发送文件名
sendto(iClientFD, acFileName, iNum, 0, (struct sockaddr*)&clientAddr, sizeof(clientAddr));
// 发送文件字节数
sendto(iClientFD, acFileByteNum, strlen(acFileByteNum), 0, (struct sockaddr*)&clientAddr, sizeof(clientAddr));
// 发送文件
int iIndex = 0;
rewind(pFile);
for(i=0; i {
for(j=0; j<255; j++)
acStr[j] = fgetc(pFile);
//printf("%s
", acStr);
sendto(iClientFD, acStr, 255, 0, (struct sockaddr*)&clientAddr, sizeof(clientAddr));
iIndex += 255;
#ifdef MINGW32
Sleep(10);
#else
usleep(10);
#endif
}
// 发送文件剩余字节
for(i=0; i acStr[j] = fgetc(pFile);
sendto(iClientFD, acStr, iByteNum%255, 0, (struct sockaddr*)&clientAddr, sizeof(clientAddr));
// 关闭文件
fclose(pFile);
// 关闭连接
closeUDP(iClientFD);
}
int main(void)
{
char acDirName[255];
char acDirAndFileName[1024];
char acIpAddr[15];
int iOption = 0;
option:
printf("%s
", "请输入选项,1.发送文件、2.接收文件:");
scanf("%d", &iOption);
if(iOption == 1)
{
fileName:
printf("%s
", "请输入需要发送的文件名,不能有空格,例如:C:\englishA.txt:");
scanf("%s", acDirAndFileName);
FILE* pFile = fopen(acDirAndFileName, "rb");
if(pFile == NULL)
{
printf("%s
", "读取文件失败,请重新输入文件名。");
goto fileName;
}
printf("%s
", "请输入接收文件方的 IP 地址,不能有空格,例如:192.168.1.104:");
scanf("%s", acIpAddr);
sendFile(acDirAndFileName, acIpAddr);
}
else if(iOption == 2)
{
printf("%s
", "请输入保存文件的路径名,不能有空格,例如:C:\img\:");
scanf("%s", acDirName);
recvFile(acDirName);
}
else
{
printf("%s
", "没有这个选项,请重新输入。");
goto option;
}
return 0;
}
Windows VC 编译命令:cl -EHsc main.c
Windows MINGW 编译命令:gcc main.c -o main.exe -l ws2_32
Linux GCC 编译命令:gcc main.c -o main -l m
在 Linux 下编译需要把 #define MINGW32 这一行注释掉
#include
#include
#include
#include
#define MINGW32
#ifdef MINGW32
#include
#include
#pragma comment(lib, "ws2_32.lib")
#else
#include
#include
#include
#endif
struct sockaddr_in serverAddr, clientAddr, remoteAddr;
int strToInt(char* acStr)
{
int i, iIndex = 0, iNum = 0, iSize = strlen(acStr);
if(acStr[0] < '0' || acStr[0] > '9')
iIndex = 1;
for(i=iIndex; i
if(acStr[0] == '-')
iNum = - iNum;
return iNum;
}
void intToStr(int iInt, char* acStr)
{
int iIndex = 0, iSize, iNum, iBit, i, j;
if(iInt < 0)
{
acStr[0] = '-';
iInt = - iInt;
iIndex = 1;
}
for(i=0; ; i++)
if(iInt < pow(10, i))
break;
iSize = i;
for(i=0; i
iNum = pow(10, iSize - i - 1);
iBit = iInt/iNum;
iInt -= iNum*iBit;
acStr[i + iIndex] = iBit + 48;
}
if(iSize != 0)
acStr[iSize + iIndex] = '';
else
{
acStr[0] = '0';
acStr[1] = '';
}
}
int serverUDP(void)
{
int iRet, iServerFD;
#ifdef MINGW32
// Winsows 启用 socket
WSADATA wsadata;
if(WSAStartup(MAKEWORd(1, 1), &wsadata) == SOCKET_ERROR)
{
printf("启用 socket 失败
");
return 0;
}
#endif
// 新建 socket
if((iServerFD = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("新建 socket 失败
");
return 0;
}
// 清零
memset(&serverAddr, 0, sizeof(serverAddr));
// 设置协议
serverAddr.sin_family = AF_INET;
// 设置 IP
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
// 设置 Port
serverAddr.sin_port = htons(1024);
// 绑定端口,监听 1024 端口的任何请求
iRet = bind(iServerFD, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(iRet == -1)
{
printf("绑定端口失败
");
return 0;
}
return iServerFD;
}
int clientUDP(char* acIpAddr)
{
int iClientFD;
#ifdef MINGW32
//Winsows下启用socket
WSADATA wsadata;
if(WSAStartup(MAKEWORd(1, 1), &wsadata) == SOCKET_ERROR)
{
printf("启用 socket 失败
");
return 0;
}
#endif
// 新建 socket
if((iClientFD = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("新建 socket 失败
");
return 0;
}
// 设置协议及Port
memset(&serverAddr, 0, sizeof(serverAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_port = htons(1024);
// 设置需要连接的服务器 IP
clientAddr.sin_addr.s_addr = inet_addr(acIpAddr);
return iClientFD;
}
void closeUDP(int iSocketFD)
{
#ifdef MINGW32
// Winsows 关闭 socket
closesocket(iSocketFD);
WSACleanup();
#endif
}
void recvFile(char* acDirName)
{
int iServerFD = serverUDP();
int iSize = sizeof(remoteAddr);
int iFileSize, iByteNum, iNum;
char acFileName[255];
char acDirAndFileName[255];
char acStr[255];
// 获取文件名
iByteNum = recvfrom(iServerFD, acFileName, 255, 0, (struct sockaddr*)&remoteAddr, &iSize);
acFileName[iByteNum] = '';
printf("文件名为:%s
", acFileName);
// 连接路径名和文件名
strcat(acDirName, acFileName);
// 获取文件字节数
iByteNum = recvfrom(iServerFD, acStr, 255, 0, (struct sockaddr*)&remoteAddr, &iSize);
acStr[iByteNum] = '';
iFileSize = strToInt(acStr);
printf("文件字节数为:%d
", iFileSize);
FILE* pFile = fopen(acDirName, "ab");
int i;
if(iFileSize%255 == 0)
iNum = iFileSize/255;
else
iNum = iFileSize/255 + 1;
for(i=0; i
iByteNum = recvfrom(iServerFD, acStr, 255, 0, (struct sockaddr*)&remoteAddr, &iSize);
fwrite(acStr, sizeof(char), iByteNum, pFile);
}
fclose(pFile);
closeUDP(iServerFD);
}
void sendFile(char* acDirAndFileName, char* acIpAddr)
{
int iClientFD, iByteNum, iNum, iSize, i, j;
char acFileName[1024];
char acFileByteNum[1024];
char acStr[256];
FILE* pFile = NULL;
pFile = fopen(acDirAndFileName, "rb");
// 文件字节数
fseek(pFile, 0, SEEK_END);
iByteNum = ftell(pFile);
intToStr(iByteNum, acFileByteNum);
//printf("%s
", acDirAndFileName);
// 获取文件名长度
iSize = strlen(acDirAndFileName);
for(i=iSize-1, iNum=0; i>=0; i--,iNum++)
if(acDirAndFileName[i] == '\' || acDirAndFileName[i] == '/')
break;
//printf("%d
", iNum);
// 截取文件名
for(i=0; i
acFileName[iNum] = '';
//printf("%s
", acFileName);
iClientFD = clientUDP(acIpAddr);
// 发送文件名
sendto(iClientFD, acFileName, iNum, 0, (struct sockaddr*)&clientAddr, sizeof(clientAddr));
// 发送文件字节数
sendto(iClientFD, acFileByteNum, strlen(acFileByteNum), 0, (struct sockaddr*)&clientAddr, sizeof(clientAddr));
// 发送文件
int iIndex = 0;
rewind(pFile);
for(i=0; i
for(j=0; j<255; j++)
acStr[j] = fgetc(pFile);
//printf("%s
", acStr);
sendto(iClientFD, acStr, 255, 0, (struct sockaddr*)&clientAddr, sizeof(clientAddr));
iIndex += 255;
#ifdef MINGW32
Sleep(10);
#else
usleep(10);
#endif
}
// 发送文件剩余字节
for(i=0; i
sendto(iClientFD, acStr, iByteNum%255, 0, (struct sockaddr*)&clientAddr, sizeof(clientAddr));
// 关闭文件
fclose(pFile);
// 关闭连接
closeUDP(iClientFD);
}
int main(void)
{
char acDirName[255];
char acDirAndFileName[1024];
char acIpAddr[15];
int iOption = 0;
option:
printf("%s
", "请输入选项,1.发送文件、2.接收文件:");
scanf("%d", &iOption);
if(iOption == 1)
{
fileName:
printf("%s
", "请输入需要发送的文件名,不能有空格,例如:C:\englishA.txt:");
scanf("%s", acDirAndFileName);
FILE* pFile = fopen(acDirAndFileName, "rb");
if(pFile == NULL)
{
printf("%s
", "读取文件失败,请重新输入文件名。");
goto fileName;
}
printf("%s
", "请输入接收文件方的 IP 地址,不能有空格,例如:192.168.1.104:");
scanf("%s", acIpAddr);
sendFile(acDirAndFileName, acIpAddr);
}
else if(iOption == 2)
{
printf("%s
", "请输入保存文件的路径名,不能有空格,例如:C:\img\:");
scanf("%s", acDirName);
recvFile(acDirName);
}
else
{
printf("%s
", "没有这个选项,请重新输入。");
goto option;
}
return 0;
}
全部回答
- 1楼网友:一袍清酒付
- 2021-11-28 01:13
你好!是DOS下的程序吗?
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯