UDP编程实现文件下载基础模板可以参考:
linux系统编程-SOCKET通信基础编程(0)-UDP编程
linux系统编程-SOCKET通信基础编程(1)-UDP编程服务端程序
linux系统编程-SOCKET通信基础编程(2)-UDP编程客户端程序
程序原理:就是增加了文件的读写操作
服务端程序
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#define SERVER_PORT 8888
#define BUFLEN 256
int setup_socket()
{
//1,创建socket
int sock_server = socket(AF_INET, SOCK_DGRAM, 0);
if(sock_server < 0)
{
perror("socket");
return -1;
}
//2,填充地址信息
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
//设置可以复用地址
int on = 1;
if(setsockopt(sock_server, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1){
perror("setsockopt");
return -1;
}
//3,bind
if(bind(sock_server, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
return -1;
}
return sock_server;
}
int main(int argc, char *argv[])
{
char buf[BUFLEN] = {0};
int ret = 0, server_sock;
struct sockaddr_in client_addr;
bzero(&client_addr, sizeof(client_addr));
socklen_t len = sizeof(client_addr);
FILE *srcFile = NULL; // 源文件
int numByte = 0; // 获取当前读取的字节数
int IsEnd = 1; //是否都取结束
int IsCloseServer = 1; //是否结束服务端程序
server_sock = setup_socket();
if(server_sock < 0)
{
return -1;
}
while(1)
{
//4, 收数据
ret = recvfrom(server_sock, buf, BUFLEN-1, 0, (struct sockaddr*)&client_addr, &len);
if( ret < 0 )
{
perror("recvfrom");
continue;
}
printf("client ip:%s, port: %d\n", (char *)inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
printf("recvfrom : %s\n", buf);
//判断当前目录下有没有该文件,以只读方式打开,没有则返回
srcFile = fopen(buf, "r");
if (NULL == srcFile) // 检查打开情况
{
perror(buf);
return -1;
}
//bzero(buf, sizeof(buf));
memset(buf,0,BUFLEN);
//若存在该文件,则循环读取文件内容发送给客户端
while(IsEnd)
{
//从源文件中读取内容
numByte = fread(buf, 1, BUFLEN, srcFile);
//5,发送数据
//strcpy(buf, "Hello World\n");
//sleep(1);
ret = sendto(server_sock, buf, numByte, 0, (const struct sockaddr * )&client_addr, len);
//bzero(buf, sizeof(buf));
if( ret == 0 )
{
memset(buf,0,BUFLEN);
break;
}
memset(buf,0,BUFLEN);
//从源文件中读取内容
numByte = fread(buf, 1, BUFLEN, srcFile);
if(feof(srcFile) && numByte == 0)
{
//服务器关闭了连接
//文件不存在
IsEnd=0;
memset(buf,0,BUFLEN);
printf("feof(srcFile) && numByte == 0\n");
ret = sendto(server_sock, buf, numByte, 0, (const struct sockaddr * )&client_addr, len);
break;
}
}
//关闭打开的文件
fclose(srcFile);
//5,发送数据
// bzero(buf, sizeof(buf));
// strcpy(buf, "Hello World\n");
// sleep(1);
// ret = sendto(server_sock, buf, strlen(buf), 0, (const struct sockaddr * )&client_addr, len);
// if( ret < 0 )
// {
// perror("sendto");
// }
}
return ret;
}
客户端程序
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#define SERVER_PORT 8888
#define CLIENT_PORT 6789
#define BUFLEN 256
int main(int argc, char *argv[])
{
int ret = 0;
char buf[BUFLEN] = {0};
struct sockaddr_in server_addr;
socklen_t socklen = sizeof(server_addr);
bzero(&server_addr, sizeof(server_addr));
FILE *newFile = NULL; // 目标文件
int numByte = 0; // 获取当前读取的字节数
//1,创建socket
int cli_sock = socket(AF_INET, SOCK_DGRAM, 0);
if(cli_sock < 0)
{
perror("socket");
return -1;
}
//可选,
struct sockaddr_in cli_addr;
bzero(&cli_addr, sizeof(cli_addr));
cli_addr.sin_family = AF_INET;
cli_addr.sin_port = htons(CLIENT_PORT);
cli_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(cli_sock, (struct sockaddr *)&cli_addr, sizeof(cli_addr)) < 0)
{
perror("bind");
goto sock_err;
}
//2,填写服务器地址信息
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
//3,发送
//strcpy(buf, "I am a client");
if(argc == 3)
{
strcpy(buf,argv[1]); //发送文件名给服务器
ret = sendto(cli_sock, buf, strlen(buf), 0, (struct sockaddr *)&server_addr, socklen);
if( ret < 0)
{
perror("sendto");
goto sock_err;
}
}else
{
printf("请输入正确的需要下载的文件信息\n");
return 0;
}
//4,接收
bzero(buf, sizeof(buf));
ret = recvfrom(cli_sock, buf, BUFLEN, 0, (struct sockaddr *)&server_addr, &socklen);
if( ret < 0 )
{
perror("recvfrom");
goto sock_err;
}else if(ret == 0)
{
printf("ret == 0\n");
return 0;
//服务器关闭了连接
//文件不存在
}
printf("===srecvfrom:%s\n", buf);
newFile = fopen(argv[2],"w");
if (NULL == newFile)
{
perror("2.txt");
return -1;
}
//bzero(buf, BUFLEN);
while(1)
{
//把buf中的内容写到文件中
//write(fd, buf,....)
//把从源文件读取到的容写入到目标文件中
printf("ret = %d\n", ret);
fwrite(buf,ret,1, newFile);
memset(buf,0,BUFLEN);
ret = recvfrom(cli_sock, buf, BUFLEN, 0, (struct sockaddr *)&server_addr, &socklen);
printf("ret = %d\n", ret);
if(ret <= 0)
{
//服务器关闭了连接
//文件不存在
break;
}
}
//关闭打开的文件
fclose(newFile);
sock_err:
//5,关闭socket
close(cli_sock);
return 0;
}