Linux -- tcp单向文件传输例程

tcp_send_file.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>        
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>    
#include <unistd.h>
 
#define handle_error(msg) \
	do { perror(msg); exit(EXIT_FAILURE); } while(0)

int
main(int argc, const char *argv[]){
	
	FILE *fp;
	int tcp_fd;
	ssize_t send_size;
	char send_buf[200]={0};
	struct sockaddr_in remote_addr; /*远程ip地址*/
	int size_number=0;
	remote_addr.sin_family=AF_INET; /*IPv4协议*/
	remote_addr.sin_addr.s_addr=inet_addr(argv[2]); /*远程服务器ip*/
	remote_addr.sin_port=htons(atoi(argv[3])); /*远程服务器端口号*/
	
	if(argc!=4){		
		fprintf(stderr,"Usage: %s <filename> <remote_ip> <remote_port>\n",argv[0]);
		exit(EXIT_FAILURE);		
	}
	
	if((fp = fopen(argv[1], "r")) == NULL){ /*以只读方式打开文件*/		
		handle_error("fopen");		
	}
	
	if((tcp_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ 
		fclose(fp); /*关闭只读文件*/
		handle_error("socket");		/*创建套接字文件*/
	}
	
	if((-1==connect(tcp_fd, (struct sockaddr *)&remote_addr,sizeof(struct sockaddr_in)))){
		fclose(fp); /*关闭只读文件*/
		close(tcp_fd); /*关闭套接字文件*/
		handle_error("connect");		/*连接失败*/
	}
	
	while(NULL != fgets(send_buf, sizeof(send_buf)-1, fp)){
										/*按行读文件内容*/		
		if((send_size=send(tcp_fd, (char *)send_buf, strlen(send_buf), 0))==-1){
			fclose(fp); /*关闭只读文件*/
			close(tcp_fd); /*关闭套接字文件*/
			handle_error("send");		/*连接失败*/
		}
		
		system("clear"); /*清屏显示发送的字节数*/
		printf("发送的字节数:%d\n",size_number=size_number+send_size);
		usleep(8000);
		
		bzero(send_buf, sizeof(send_buf));	/*清空发送buf*/
		
	}
	
	fclose(fp); /*关闭只读文件*/
	close(tcp_fd); /*关闭套接字文件*/
	
	return 0;
}

/**
 * struct sockaddr_in {     //保存ipv4地址与端口号的通用地址结构体
 * 	 __kernel_sa_family_t  sin_family;     //地址协议   AF_INET
 *	 __be16                sin_port;       //端口号
 * 	 struct in_addr        sin_addr;       //ip地址
 *	 unsigned char         __pad[8];               //用于凑字节,保证强制类型转换数据完整                   
 * };
 */
/**
 * struct in_addr {         //专门存放ip地址的结构体
 *  in_addr_t s_addr;
 * };
 */

tcp_recv_file.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>        
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>    
 
#define handle_error(msg) \
	do { perror(msg); exit(EXIT_FAILURE); } while(0)

int
main(int argc, const char *argv[]){
	
	FILE *fp;
	int tcp_fd;
	int cfd;
	int addrlen;
	int size_number;
	ssize_t recv_size;	
	char recv_buf[200]={0};
	struct sockaddr_in remote_addr; /*本地ip地址*/
	struct sockaddr_in save_addr; 	/*保存的地址*/
	
	remote_addr.sin_family=AF_INET; /*IPv4协议*/
	remote_addr.sin_addr.s_addr=inet_addr(argv[2]); 	/*远程服务器ip*/
	remote_addr.sin_port=htons(atoi(argv[3])); 	/*远程服务器端口号*/
	
	if(argc!=4){		
		fprintf(stderr,"Usage: %s <save_filename> <local_ip> <local_port>\n",argv[0]);
		exit(EXIT_FAILURE);		
	}
	
	if((fp = fopen(argv[1], "w")) == NULL){ /*以只写方式打开文件,文件不存在则创建文件*/		
		handle_error("fopen");		
	}
	
	if((tcp_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ 
		fclose(fp); 	/*关闭只读文件*/
		handle_error("socket");		/*创建套接字文件*/
	}
	
	if(-1 == bind(tcp_fd, (struct sockaddr *)&remote_addr,sizeof(struct sockaddr_in))){
		fclose(fp); 	/*关闭只写文件*/             			/*设置本地ip和本地端口*/
		close(tcp_fd); 	/*关闭套接字文件*/
		handle_error("bind");		/*连接失败*/
	}
	
	if(-1 == listen(tcp_fd, 7)){ 	/*网络监听*/
		fclose(fp); 	/*关闭只读文件*/
		close(tcp_fd); 	/*关闭套接字文件*/
		handle_error("listen");		/*创建套接字文件*/
	}
	
	addrlen=sizeof(struct sockaddr_in);
	if((cfd = accept(tcp_fd, (struct sockaddr *)&save_addr, &addrlen)) == -1){		
		fclose(fp); /*关闭只读文件*/
		close(tcp_fd); /*关闭套接字文件*/
		handle_error("accept");		/*创建套接字文件*/		
	}
	fprintf(stderr,"client_ip:%s, client_port:%d\n",inet_ntoa(save_addr.sin_addr),htons(save_addr.sin_port));
                                                                /* 打印客户端ip地址和端口号*/
	while(1){
										
		if((recv_size=recv(cfd, (char *)recv_buf, sizeof(recv_buf), 0))==-1){
			fclose(fp); /*关闭只读文件*/
			close(cfd); /*关闭连接成功后的文件*/
			close(tcp_fd); /*关闭套接字文件*/			
			handle_error("recv");		/*连接失败*/
		}
		
		if(0 == recv_size)
				break;
		
		if(EOF == fputs(recv_buf, fp)){ /*将接收到的数据存放到fp指定的缓冲区*/
			fclose(fp); /*关闭只读文件*/
			close(cfd); /*关闭连接成功后的文件*/
			close(tcp_fd); /*关闭套接字文件*/
			fprintf(stderr,"Error %s file!\n", argv[1]);
			exit(EXIT_FAILURE);
		}
		system("clear"); /*清屏显示接收的字节数*/
		printf("发送的字节数:%d\n",size_number=size_number+recv_size);
		
		bzero(recv_buf, sizeof(recv_buf));	/*清空接受buf*/
		
	}
	
	fclose(fp); /*关闭只读文件*/
	close(cfd); /*关闭连接成功后的文件*/
	close(tcp_fd); /*关闭套接字文件*/
	
	return 0;
}

/**
 * struct sockaddr_in {     //保存ipv4地址与端口号的通用地址结构体
 * 	 __kernel_sa_family_t  sin_family;     //地址协议   AF_INET
 *	 __be16                sin_port;       //端口号
 * 	 struct in_addr        sin_addr;       //ip地址
 *	 unsigned char         __pad[8];               //用于凑字节,保证强制类型转换数据完整                   
 * };
 */
/**
 * struct in_addr {         //专门存放ip地址的结构体
 *  in_addr_t s_addr;
 * };
 */
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值