永发信息网

请教用C语言编的借助UDP协议实现的文件传输的程序

答案:2  悬赏:50  手机版
解决时间 2021-11-28 06:08
请教用C语言编的借助UDP协议实现的文件传输的程序
最佳答案
本程序在 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;
}
全部回答
你好!是DOS下的程序吗?
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
四括号3x加6括号等于72的方程怎么解
写君子的诗句并阐述什么才是君子
单选题在自然界里,细菌是以什么形式存在A.都
有谁知道水费单中的垃圾处理费是什么费啊?
(2x+y-3)(2x+3y+7)+16 因式分解
许佳慧唱含有醉酒的歌词的歌曲
为什么抛售外汇储备,造成本国货币供应量的减
求烧脑子且集数不少于500集的动画片的说
一想到以后和男生有性关系
5米左右气瓶仓栏运输车厂家直销多少钱13872
众筹是不是谁都可以参加
诗人在本诗中成功的运用了联想。请你整理出诗
上海克络蒂新能源科技有限公司怎么样?
我爸爸在农村,我感觉我爸爸心理狠毒,找人杀
哪个是解压
推荐资讯
这个字嚷怎么读
今年28岁八月份怀孕是生男孩还是生女孩
腾讯360腾讯由封闭走向开放的原因是什么
只有qq帐号怎么登别人的q
着急啊,有电脑高手在吗
女生八字是甲戌丙子戊寅戊午,想知道命好不好
这个程序的功能是输出5*5魔方阵,请问错在哪
如何推销保健品?
win10怎么合并磁盘分区
我有一双新百伦996DG,灰色的鞋大家都是怎么
南平到万年多少公里
单选题Therewere________peopleattheco
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?