日期:2014-05-16 浏览次数:20754 次
LINUX C 基于TCP/IP协议的SOCKET收发文件的小例子。
自已没事正看这方面的东西,感觉要想把网络这块弄明白还真不是件简单的事。
程序写的比较繁琐,代码也不合理,有时间再把程序优化一下,加上断点继传的功能。。
/******** http://blog.csdn.net/robertkun ********/ /******* 服务器程序 (server.c) ************/ // linux 下读取大于2GB文件时,需指定 #define _FILE_OFFSET_BITS 64 #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <netdb.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/types.h> #include <arpa/inet.h> #include <fcntl.h> // 定义包的大小为512KB #define PACK_SIZE 1025*512 int main(int argc, char *argv[]) { // 设置输出缓冲 setvbuf(stdout, NULL, _IONBF, 0); fflush(stdout); int sockfd,new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size,portnumber; char hello[]="Hello! Are You Fine?\n"; if((portnumber=atoi("8080"))<0) { fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); exit(1); } /* 服务器端开始建立socket描述符 */ if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); exit(1); } /* 服务器端填充 sockaddr结构 */ bzero(&server_addr,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(portnumber); /* 捆绑sockfd描述符 */ if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) { fprintf(stderr,"Bind error:%s\n\a",strerror(errno)); exit(1); } /* 监听sockfd描述符 */ if(listen(sockfd,5)==-1) { fprintf(stderr,"Listen error:%s\n\a",strerror(errno)); exit(1); } while(1) { fprintf(stderr, "server is listening!\n"); /* 服务器阻塞,直到客户程序建立连接 */ sin_size=sizeof(struct sockaddr_in); if( ( new_fd = accept(sockfd,(struct sockaddr *)(&client_addr),(socklen_t*)&sin_size ) ) == -1) { fprintf(stderr,"Accept error:%s\n\a",strerror(errno)); exit(1); } fprintf(stderr,"Server get connection from %s\n", inet_ntoa(client_addr.sin_addr)); if(write(new_fd,hello,strlen(hello))==-1) { fprintf(stderr,"Write Error:%s\n",strerror(errno)); exit(1); } int read_size = 0; unsigned long file_len = 0; int order_id = 0; char file_name[128] = {'\0'}; char file_info[1024] = {'\0'}; // 读取指令 if(read(new_fd, file_info, 1024)) { // 指令ID int id_h = (int)file_info[0]<<8; order_id = id_h + (int)file_info[1]; // 文件长度 // 高16位 int len_h_1 = (int)file_info[2]<<8; int len_h_2 = len_h_1 + (int)file_info[3]; int len_h = len_h_2 << 16; // 低16位 int len_l_1 = (int)file_info[4]<<8; int len_l = len_l_1 + (int)file_info[5]; file_len = len_h + len_l; // 文件名称 strncpy(file_name, &file_info[6], strlen(&file_info[6])); printf("order = %d, %lu, %s\n", order_id, file_len, file_name); } else { printf("Read file error!\n"); close(new_fd); close(sockfd); exit(0); } // 写入文件 FILE* pf = fopen(file_name, "wb+"); char buff[PACK_SIZE] = {'\0'}; while(read_size <= file_len) { //bzero(buff, 1024); int rlen = read(new_fd, buff, PACK_SIZE); if(rlen) { system("clear"); printf("Read package size = %d\n", rlen); fwrite(buff, sizeof(cha