• 在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 
    ",filename.c_str());
            } 
            else
            {
                printf("send file %d fail.The error code is : %d 
    ",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...
    ");
            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!
    ");
                close(newSocket);
                continue;
            }
            strncpy(file_name,buffer,strlen(buffer));
            printf("recv file name : %s 
    ",file_name);
            FILE * fp = fopen(file_name,"wb");
            if (fp==NULL)
            {
                printf("open file error
    ");
                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
    ", file_name); 
                    break; 
                } 
                memset(buffer, 0, BUFFER_SIZE); 
            }
            fclose(fp);
            close(newSocket);
            printf("file transfer success!
    "); 
        }
          
        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函数来实现。

  • 相关阅读:
    基于docker安装pxc集群
    PXC集群的概述及搭建
    十,StatefulSet简介及简单使用
    九,configMap及secret的基本使用
    八,kubernetes集群存储卷基础。
    七,ingress及ingress cluster
    六,k8s集群service资源
    mysql的优化
    ORACLE11g:No Dialect mapping for JDBC type: -9解决方案
    Oracle数据库的分页
  • 原文地址:https://www.cnblogs.com/xiongmao-cpp/p/5218673.html
Copyright © 2020-2023  润新知