在windows 与Linux间实现文件传输(C++&C实现)

  要实现windows与linux间的文件传输,可以通过socket网络编程来实现。

  这次要实现的功能与《Windows下通过socket进行字符串和文件传输》中实现的功能相同,即客户端首先向服务器发送一个字符串,接着发送一个文件;服务器首先接收客户端发送的字符串,作为文件名,接着接收客户端发送的文件并保存到本地。

  以window平台程序作为客户端,linux平台的程序作为服务器,并且是在局域网范围内进行文件传输。

  windows客户端的实现:

  客户端程序在VS2012 IDE下编译运行,依旧使用在《Windows下通过socket进行字符串和文件传输》中简单封装实现的FileTransfer类,通过声明一个FileTransfer对象并调用相应的函数来发送数据和文件。其main函数如下:

/************************************************************************* 
  > File Name: 客户端主函数
  >Author: xiongmao
  >Purpose:在主函数中声明文件传输类的一个具体对象,向linux服务器发送文件
 ************************************************************************/ 

#include <iostream>
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "file_transfer.h"
using namespace std;

int PORT;
string SERVER_IP ="127.0.0.1" ;
#define BUFFER_SIZE 1024 
#define FILE_NAME_MAX_SIZE 512 
#pragma comment(lib, "WS2_32") 
 
int main() 
{ 
    cout<<"input ip and port"<<endl;
    cin>>SERVER_IP>>PORT;
    while(1)
    {
        bool flag;
        string filename;
        printf("input file name:");
        cin>>filename;
        FileTransfer ft;
        ft.setIpAndPort(SERVER_IP,PORT);
        ft.setFilePath(filename);
        flag=ft.sendFile(filename,filename);
        if (flag)
        { 
            printf("send file %s success \n",filename.c_str());
        } 
        else
        {
            printf("send file %d fail.The error code is : %d \n",GetLastError());
        }
    }
    system("pause");
    return 0; 
} 

  在主函数开始时,首先输入服务器的ip地址和端口,接着输入想要发送的文件名(文件应在源码目录下存在),客户端就可完成文件袋额发送。

 

  linux服务器的代码:

  linux下仅使有一个main.cpp文件,实现简单的服务器功能,其代码如下:

//main.cpp

#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> 

#include <stdio.h>          
#include <stdlib.h>         
#include <string.h>         

#define HELLO_WORLD_SERVER_PORT 8989  
#define LENGTH_OF_LISTEN_QUEUE 20  
#define BUFFER_SIZE 1024  
  
int main(int argc, char **argv)  
{  
    struct sockaddr_in server_addr;  
    int server_socket;  
    int opt = 1;  
     
    bzero(&server_addr,sizeof(server_addr));   
      
    server_addr.sin_family = AF_INET;  
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);  
    server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); 
  
    /* create a socket */  
    server_socket = socket(PF_INET,SOCK_STREAM,0);  
    if( server_socket < 0)  
    {  
        printf("Create Socket Failed!");  
        exit(1);  
    }  
   
    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); 
    if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)))  
    {  
        printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT);   
        exit(1);  
    }  

    if(listen(server_socket, LENGTH_OF_LISTEN_QUEUE))  
    {  
        printf("Server Listen Failed!");   
        exit(1);  
    }  
       
    while (true)
    {
        printf("wait for file transfer...\n");
        char file_name[BUFFER_SIZE];
        char buffer[BUFFER_SIZE];

        struct sockaddr_in client_addr; 
        socklen_t client_addr_len = sizeof(client_addr); 
        //首先接收发送过来的字符串
        int newSocket = accept( m_Socket, (sockaddr *)&client_addr, &client_addr_len);
        if (newSocket < 0) 
        { 
            printf("Server Accept Failed: %d", WSAGetLastError()); 
            continue; 
        } 
        memset(buffer,0,sizeof(buffer));
        memset(file_name,0,sizeof(file_name));
        if (recv(newSocket,buffer,sizeof(buffer),0)<0)
        {
            printf("recv file name fail!\n");
            close(newSocket);
            continue;
        }
        strncpy(file_name,buffer,strlen(buffer));
        printf("recv file name : %s \n",file_name);
        FILE * fp = fopen(file_name,"wb");
        if (fp==NULL)
        {
            printf("open file error\n");
            continue;
        }
        //获取字符串后继续获取文件数据
        memset(buffer, 0, BUFFER_SIZE); 
        int length = 0; 
        while ((length = recv(newSocket, buffer, BUFFER_SIZE, 0)) > 0) 
        { 
            if (fwrite(buffer, sizeof(char), length, fp) < length) 
            { 
                printf("File: %s Write Failed\n", file_name); 
                break; 
            } 
            memset(buffer, 0, BUFFER_SIZE); 
        }
        fclose(fp);
        close(newSocket);
        printf("file transfer success!\n"); 
    }
      
    close(server_socket);  
    return 0;  
}  

   在linux下,进入main.cpp所在的目录,使用命令

gcc main.cpp -o main.out

来编译服务器端程序,再使用命令

./main.out

 来执行编译的程序,即可启动服务器。

 

  通过比较《Windows下通过socket进行字符串和文件传输》中服务器程序的实现,观察到代码实现基本上一致,linux下的实现存在以下几点不同:

  1、linux下用来绑定端口,实现监听的socket server_socket的声明为int类型,而在window下则为SOCKET类型。

  2、linux下,关闭socket的函数为close,使用该函数需要包含unistd.h头文件,windows下则是用closesocket来关闭socket。

  3、使用bzero函数来进行置零操作。bzero函数不是标准函数,不推荐使用。非标准函数的使用会对程序的移植造成不便。bzero函数的功能可以用memset函数来实现。

 

posted @ 2016-02-25 22:44  Num.Zero  阅读(5315)  评论(2编辑  收藏  举报