Socket网络程序设计(3) ———— 利用tcp完成文件传输的设计和实现
2017-08-10 09:55
501 查看
用TCP/TP进行网际互连(3)
———— 利用tcp完成文件传输的设计和实现1、要求介绍
利用循环面向连接的模型完成固定文件的传输由固定文件扩展成手动输入或选择文件
——废话少说,直接上代码——
2、实现代码
服务器:(1.初始化服务器端的socket:) int sockfd,connfd; struct sockaddr_in svraddr,clientaddr; bzero(&svraddr,sizeof(svraddr)); svraddr.sin_family=AF_INET; svraddr.sin_addr.s_addr=htonl(INADDR_ANY); svraddr.sin_port=htons(PORT); sockfd=socket(AF_INET,SOCK_STREAM,0); (2.进行绑定:) if(bind(sockfd,(struct sockaddr*)&svraddr,sizeof(svraddr))<0) { perror("bind"); exit(1); } (3.变为被动模式,进行监听) //listen if(listen(sockfd,LISTENQ)<0) { perror("listen"); exit(1); } (4.循环等待实现文件的传输) while(1) { socklen_t length=sizeof(clientaddr); //accept connfd=accept(sockfd,(struct sockaddr*)&clientaddr,&length); if(connfd<0) { perror("connect"); exit(1); } //send file imformation char buff[BUFFSIZE]; int count; bzero(buff,BUFFSIZE); strncpy(buff,filename,strlen(filename)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(filename)); count=send(connfd,buff,BUFFSIZE,0); if(count<0) { perror("Send file information"); exit(1); } //read file FILE *fd=fopen(filename,"rb"); if(fd==NULL) { printf("File :%s not found!\n",filename); } else { bzero(buff,BUFFSIZE); int file_block_length=0; while((file_block_length=fread(buff,sizeof(char),BUFFSIZE,fd))>0) { printf("file_block_length:%d\n",file_block_length); if(send(connfd,buff,file_block_length,0)<0) { perror("Send"); exit(1); } bzero(buff,BUFFSIZE); } fclose(fd); printf("Transfer file finished !\n"); } close(connfd); }
客户端
主函数: int main(int argc, char **argv[]) { int clientfd; //连接 clientfd=connectTCP("127.0.0.1",PORT); //接收信息 recvTCP(clientfd); //关闭 close(clientfd); return 0; } (可以看出整个主函数变得非常简洁) //connectTCP函数封装了TCP的连接过程 int connectTCP(const char *host, const char *port){ int clientfd; struct sockaddr_in clientaddr; bzero(&clientaddr,sizeof(clientaddr)); clientaddr.sin_family=AF_INET; clientaddr.sin_addr.s_addr=htons(INADDR_ANY); clientaddr.sin_port=htons(0); clientfd=socket(AF_INET,SOCK_STREAM,0); if(clientfd<0) { perror("socket"); exit(1); } if(bind(clientfd,(struct sockaddr*)&clientaddr,sizeof(clientaddr))<0) { perror("bind"); exit(1); } struct sockaddr_in svraddr; bzero(&svraddr,sizeof(svraddr)); if(inet_aton(host,&svraddr.sin_addr)==0) { perror("inet_aton"); exit(1); } svraddr.sin_family=AF_INET; svraddr.sin_port=htons(port); socklen_t svraddrlen=sizeof(svraddr); if(connect(clientfd,(struct sockaddr*)&svraddr,svraddrlen)<0) { perror("connect"); exit(1); } return clientfd; } //recvTCP封装了接收文件的过程 void recvTCP(int clientfd){ //recv file imformation char buff[BUFFSIZE]; char filename[FILE_NAME_MAX_SIZE]; int count; bzero(buff,BUFFSIZE); count=recv(clientfd,buff,BUFFSIZE,0); if(count<0) { perror("recv"); exit(1); } strncpy(filename,buff,strlen(buff)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buff)); printf("Preparing recv file : %s \n",filename); //recv file FILE *fd=fopen(filename,"wb+"); if(NULL==fd) { perror("open"); exit(1); } bzero(buff,BUFFSIZE); int length=0; while(length=recv(clientfd,buff,BUFFSIZE,0)) { if(length<0) { perror("recv"); exit(1); } int writelen=fwrite(buff,sizeof(char),length,fd); if(writelen<length) { perror("write"); exit(1); } bzero(buff,BUFFSIZE); } printf("Receieved file:%s finished!\n",filename); fclose(fd); }
3、代码分析
首先在服务器端利用循环面向连接的模型进行文件的传输,实现向每一个接入的客户端发送文件的服务。文件名可以手动输入来选择文件。客户端程序进行相应的socket连接。进行封装之后,简化了主函数,使主函数变得简洁清晰了很多,通过调用connectTCP进行socket函数连接的封装,方便之后的扩展,如添加一个基于UDP协议的传输服务。
4、运行效果
服务器端启动,选择要传输的文件:客户端连接:
测试,当传输稍大文件时:
附上我的测试成功的实验代码:
https://github.com/KevinBetterQ/Network-programming/tree/master/TCP_file
相关文章推荐
- 利用TCP/UDP完成文件传输的设计和实现
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计1
- 利用TCP协议通过Socket编写的网络聊天工具2-通用类设计
- 利用TCP协议通过Socket编写的网络聊天工具3-服务器端设计
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计2
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计1[使用IE浏览本页]
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计2[使用IE浏览本页]
- C++ 利用socket实现TCP,UDP网络通讯
- DirectX编程:C#中利用Socket实现网络语音通信[初级版本]
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(二)----使用方法
- 利用TCP传输协议实现基于Socket的聊天程序
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(二)----使用方法
- iOS网络编程实践–NSStream实现TCP Socket iPhone客户端
- iOS网络编程实践--NSStream实现TCP Socket iPhone客户端
- .Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务2[使用IE浏览本页]
- Socket 基础 非阻塞式TCP socket,实现文件传输jpg,mov等格式
- [转]在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(二)
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架