Linux socket编程(五) 文件传输

来源:互联网 发布:人文社会科学类软件 编辑:程序博客网 时间:2024/05/22 11:49

http://www.cnblogs.com/-Lei/archive/2012/09/16/2687170.html

这一篇给之前写的聊天室再加上文件传输:

  以下是对文件操作的封装

      FileOperator.h

复制代码
#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

复制代码
#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);}
复制代码

那怎么发送文件呢

复制代码
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;        }    }}
复制代码

接收文件

复制代码
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.");}
复制代码

要注意的是发送文件时,如果文件较大,客户端很可能会阻塞,这个时候可以开一个新线程来发送文件。

不过,这个只是很简单的文件传输,复杂点的有空再慢慢研究。


0 0
原创粉丝点击