这一篇给之前写的聊天室再加上文件传输。
以下是对文件操作的封装
FileOperator.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#ifndef FILEOPERATOR_H #define FILEOPERATOR_H #include <stdio.h> #define WRITE_CREATE_MODE "a+b" #include <fcntl.h> #include <string> class FileOperator { public: FileOperator(); ~FileOperator(); bool Open(const char* fileName,const char* option); int WriteToFile(const std::string& buffer); int ReadFromFile(std::string& buffer); void Close(); private: FILE* filePtr; }; #endif |
FileOperator.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include "FileOperator.h" #include <sys/sendfile.h> #include <memory.h> const int MAX_BUFFERLENGTH=512; FileOperator::FileOperator() :filePtr(NULL) {} FileOperator::~FileOperator() { Close(); } bool FileOperator::Open(const char* fileName,const char* option) { filePtr=fopen(fileName,option); return filePtr!=NULL; } int FileOperator::WriteToFile(const std::string& buffer) { int writeBytes=::fwrite(buffer.c_str(),sizeof(char),buffer.size(),filePtr); if(writeBytes<0) { perror("error from fwrite"); return -1; } else if(writeBytes==0) return 0; else return writeBytes; } int FileOperator::ReadFromFile(std::string& buffer) { char bufferArray[MAX_BUFFERLENGTH+1]; buffer.clear(); memset(bufferArray,0,MAX_BUFFERLENGTH+1); int numberRead=fread(bufferArray,sizeof(char),MAX_BUFFERLENGTH+1,filePtr); if(numberRead==-1) { perror("error in Socket::Receive"); return -1; } else if(numberRead==0) return 0; else { buffer=bufferArray; return numberRead; } } void FileOperator::Close() { if(filePtr!=NULL) fclose(filePtr); } |
那怎么发送文件呢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void ClientSocket::SendFile(const std::string& fileName) { FileOperator fileOperator; fileOperator.Open(fileName.c_str(),"rb"); std::string buffer; int readBytes; Send("File"); while((readBytes = fileOperator.ReadFromFile(buffer))>0) { if(Send(buffer)<0) { perror("failed to send file"); break; } } } |
接收文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
void ServerSocket::RecvFile(Socket* clientSocket) { std::string message; FileOperator fileOperator; //using IP address to name received file fileOperator.Open(clientSocket->GetAddress().c_str(),WRITE_CREATE_MODE); int recvBytes; int writeBytes; while((recvBytes=Socket::Receive(*clientSocket,message))>0) { std::cout<<"message length: "<<message.size()<<"\n"; writeBytes=fileOperator.WriteToFile(message); std::cout<<"writeBytes: "<<writeBytes<<"\n"; if(writeBytes<recvBytes) { perror("write to file failed"); Socket::Send(*clientSocket,"Error when server receiving file."); return; } //if all bytes has been wrote if(recvBytes==0 || recvBytes!=MAXRECEIVE) break; } if(recvBytes >=0 ) Socket::Send(*clientSocket,"server has received your file."); } |
要注意的是发送文件时,如果文件较大,客户端很可能会阻塞,这个时候可以开一个新线程来发送文件。
不过,这个只是很简单的文件传输,复杂点的有空再慢慢研究。
发表评论
要发表评论,您必须先登录。