linux系统编程-SOCKET通信基础编程-UDP编程实现文件下载

UDP编程实现文件下载基础模板可以参考:

linux系统编程-SOCKET通信基础编程(0)-UDP编程

linux系统编程-SOCKET通信基础编程(1)-UDP编程服务端程序

linux系统编程-SOCKET通信基础编程(2)-UDP编程客户端程序

 

程序原理:就是增加了文件的读写操作

服务端程序


#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>

#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 <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>

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


 

猜你喜欢

转载自blog.csdn.net/yuupengsun/article/details/106459987