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;
 * };
 */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章