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

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

linux系统编程-SOCKET通信基础编程(0)-常用数据结构

linux系统编程-SOCKET通信基础编程(1)-TCP客户端创建

linux系统编程-SOCKET通信基础编程(2)-TCP服务端创建

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

TCP服务端代码

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


#define SERVER_PORT 6666
#define BUFLEN 256


int setup_socket()
{
	int ret = 0;
	
	//1,创建SOCKET, 服务器的服务套接字
	int server_sock = socket(AF_INET, SOCK_STREAM, 0);
	if(server_sock < 0)
	{
		perror("socket");
		goto SOCKET_ERR;
	}
	
	//2, 填充服务器的地址信息
	struct sockaddr_in server_addr;
	bzero(&server_addr, sizeof(struct sockaddr_in));
	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(server_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1){
		perror("setsockopt");
		goto SOCKET_ERR;
	}	
	
	//3,绑定
	ret = bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
	if(ret < 0)
	{
		perror("bind");
		goto SOCKET_ERR;
	}
	
	//4, 监听
	ret = listen(server_sock, 5);
	if(ret < 0)
	{
		perror("listen");
		goto SOCKET_ERR;
	}
	
	return server_sock;

SOCKET_ERR:
	return -1;
}

int main(int argc, char *argv[])
{
	char buf[BUFLEN] = {0};
	int client_sock = 0, ret = 0;
	socklen_t addrlen = 0;
	int server_sock;
	struct sockaddr_in client_addr;
	//SOCKADDR_IN client_addr;
	
	FILE *srcFile  = NULL;  // 源文件
	int  numByte  = 0;      // 获取当前读取的字节数
	int  IsEnd = 1;         //是否都取结束
	int IsCloseServer = 1;  //是否结束服务端程序
	
	
	if(server_sock < 0)
	{
		perror("setup_socket");
		goto SOCKET_ERR;
	}	
	
	addrlen = sizeof(client_addr);
	server_sock = setup_socket();
	memset(&client_addr,0,sizeof(client_addr));
	
	while(1)
	{
		memset(buf,0,BUFLEN);
		//5, 接收连接
		client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addrlen);	

		printf("accept connect form IP: %s, port:%d\n",
			  (char *)inet_ntoa(client_addr.sin_addr.s_addr) , ntohl(client_addr.sin_port));
		
		//6, 读数据--接收文件名
		ret = recv(client_sock, buf, BUFLEN, 0);
		if(ret < 0)
		{
			perror("recv");
			goto SOCKET_ERR;
		}else if(ret == 0)
		{			
			printf("recv cliet filename:%s  %d\n", buf,ret);
		}
		printf("recv cliet filename:%s  %d\n", buf,ret);
		
		//判断当前目录下有没有该文件,以只读方式打开,没有则返回
		srcFile = fopen(buf, "r");
		if (NULL == srcFile)     // 检查打开情况
		{
			perror(buf);
			return -1;
		}
		
		memset(buf,0,BUFLEN);
		//若存在该文件,则循环读取文件内容发送给客户端
		while(IsEnd)
		{	
			//printf("recv cliet filename:%s  %d\n", buf,ret);
			//从源文件中读取内容 
			numByte = fread(buf, 1, BUFLEN, srcFile);			
			if(feof(srcFile) && numByte == 0)
			{
				//服务器关闭了连接
				//文件不存在
				memset(buf,0,BUFLEN);
				ret = send(client_sock, buf, numByte, 0);
				IsEnd=0;
				break;
			}
			//7, 发送文件内容数据
			//bzero(buf, BUFLEN);
			//strcpy(buf, "Hello World!\n");
			ret = send(client_sock, buf, numByte, 0);
			if(ret == 0)
			{IsEnd=0;
				//服务器关闭了连接
				//文件不存在
				memset(buf,0,BUFLEN);
				ret = send(client_sock, buf, numByte, 0);
				break;
			}
			memset(buf,0,BUFLEN);
		}

		//关闭打开的文件
		fclose(srcFile);
		//8,关闭连接
		close(client_sock);	

	}
	
	
SOCKET_ERR:	
	return 0;
}

TCP客户端代码

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


#define SERVER_PORT 6666
#define BUFLEN 256


int main(int argc, char *argv[])
{
	int ret = 0;
	char buf[BUFLEN] = {0};
	FILE *newFile  = NULL;  // 目标文件
	int  numByte  = 0;     // 获取当前读取的字节数
	
	//1,创建socket
	int client_sock = socket(AF_INET, SOCK_STREAM, 0);
	if(client_sock < 0)
	{
		perror("socket");
		goto SOCK_ERR;
	}
	
	//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 = inet_addr("127.0.0.1");
	
	//3,连接服务器
	ret = connect(client_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
	if(ret < 0)
	{
		perror("connect");
		goto SOCK_ERR;
	}
	memset(buf,0,BUFLEN);
	//4,发送数据
	//strcpy(buf, "I am a client\n");  //发送文件名给服务器
	if(argc == 3)//一个个参数 需要下载的文件及路径, 第二个参数存储文件路径及新的文件名
	{
		strcpy(buf,argv[1]);  //发送文件名给服务器
		ret = send(client_sock, buf, strlen(buf), 0);
		if(ret < 0)
		{
			perror("send");
			goto SOCK_ERR;
		}
	}else
	{
		printf("请输入正确的需要下载的文件信息\n");
		return 0;
	}
	
	
	//5,接收数据
	memset(buf,0,BUFLEN);
	ret = recv(client_sock, buf, BUFLEN, 0);
	if(ret < 0)
	{
		perror("recv");
		goto SOCK_ERR;
	}
	else if(ret == 0)
	{
		return 0;
		//服务器关闭了连接
		//文件不存在
	}
	
	newFile = fopen(argv[2],"w");
    if (NULL == newFile)   
    {
        perror("2.txt");
        return -1;
    }
	//bzero(buf, BUFLEN);
	while(1)
	{
		//把buf中的内容写到文件中
		//write(fd, buf,....)		
		
		//把从源文件读取到的容写入到目标文件中
		fwrite(buf,ret,1, newFile);
		memset(buf,0,BUFLEN);
		ret = recv(client_sock, buf, BUFLEN, 0);
		if(ret == 0)
		{
			//服务器关闭了连接
			//文件不存在
			break;
		}
	}
	
	//关闭打开的文件
    fclose(newFile);
	
	printf("recv msg from server:%s\n", buf);
	
	//6,关闭连接
	close(client_sock);
SOCK_ERR:
	return 0;
}

猜你喜欢

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