C++的文件传输简单版和mfc的版本

先写一个socket的连接

SOCKET InitNewSocket()
{
    //声明地址结构
    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.S_un.S_addr = INADDR_ANY;
    server_addr.sin_port = htons(PORT);

    //初始化 socket dll
    WSADATA wsaData;
    WORD socketVersion = MAKEWORD(2, 2);
    assert(WSAStartup(socketVersion, &wsaData) == 0);

    //创建socket
    SOCKET m_socket = socket(AF_INET, SOCK_STREAM, 0);
    assert(SOCKET_ERROR != m_socket);

    //绑定
    assert(SOCKET_ERROR != bind(m_socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)));

    //监听
    assert(SOCKET_ERROR != listen(m_socket, 5));

    return m_socket;
}

之后写服务端等待连接的部分

void listenToUpload()
{
    unsigned hThread1;
    unsigned ThreadID1;

    //初始化端Server套接字
    SOCKET UploadServerSocket = InitNewSocket();
    while (1)
    {
        //等待连接
        cout << "等待客户端连接 ..." << endl;
        sockaddr_in client_addr;
        int client_addr_len = sizeof(client_addr);
        SOCKET m_new_socket = accept(UploadServerSocket, (sockaddr *)&client_addr, &client_addr_len);    //创建和客户端的连接
        if (SOCKET_ERROR == m_new_socket)
        {
            cout << "连接失败" << endl;
        }
        else {
            cout << "客户端:"<<inet_ntoa(client_addr.sin_addr)<<"连接成功" << endl;
            hThread1 = _beginthreadex(NULL, 0, Server_accept_upload, (LPVOID)m_new_socket, 0, &ThreadID1);
        }
    }
    closesocket(UploadServerSocket);
    WSACleanup();
}

接受文件的部分

unsigned int _stdcall  Server_accept_upload(void *par)
{
    SOCKET m_new_socket = SOCKET(par);
    char buffer[BUFFER_SIZE];
    memset(buffer, 0, BUFFER_SIZE);
    assert(recv(m_new_socket, buffer, BUFFER_SIZE, 0) >= 0);                                //接收客户端发来的文件名
    char file_name[FILE_NAME_MAX_SIZE + 1];
    memset(file_name, 0, FILE_NAME_MAX_SIZE + 1);
    strncpy(file_name, buffer, strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));  //长度取较短的
    std::cout << "接收文件名:" << file_name << endl;

    char file[FILE_NAME_MAX_SIZE + 1];
    strcpy(file, upload_to_server_path);
    strcat(file, file_name);

    cout << file << endl;
    FILE *fp = fopen(file, "wb");  //以只写,二进制的方式打开一个文件
    assert(NULL != fp);
    memset(buffer, 0, BUFFER_SIZE);
    int length = 0;
    while ((length = recv(m_new_socket, buffer, BUFFER_SIZE, 0)) > 0)
    {
        assert(fwrite(buffer, sizeof(char), length, fp) >= (size_t)length);
        memset(buffer, 0, BUFFER_SIZE);
    }
    std::cout << "来自客户端的上传文件 : " << file_name << endl << " 上传成功 !" << std::endl;
    fclose(fp);
    closesocket(m_new_socket);
    return 0;
}

本项目采用的是单词连接方式,传完之后又需要客户端再次连接

void listenToDownload()
{
    unsigned hThread1;
    unsigned ThreadID1;
    //初始化端Server套接字
    SOCKET DownloadServerSocket = InitNewSocket();
    while (1)
    {
        //等待连接
        std::cout << "等待客户端连接 ..." << std::endl;
        sockaddr_in client_addr;
        int client_addr_len = sizeof(client_addr);
        SOCKET m_new_socket = accept(DownloadServerSocket, (sockaddr *)&client_addr, &client_addr_len);
        if (m_new_socket!=INVALID_SOCKET)
        {
            cout << "客户端:" << inet_ntoa(client_addr.sin_addr) << "连接成功" << endl;
            hThread1 = _beginthreadex(NULL, 0, Server_accept_download, (LPVOID)m_new_socket, 0, &ThreadID1);
        }
        else cout << "连接失败" << endl;
        
    }
    
    closesocket(DownloadServerSocket);
    //释放 winsock 库
    WSACleanup();
}

服务端的最后就是向客户端发送文件

unsigned int _stdcall  Server_accept_download(void *par)
{
    SOCKET m_new_socket = SOCKET(par);
    char buffer[BUFFER_SIZE];
    memset(buffer, 0, BUFFER_SIZE);
    assert(recv(m_new_socket, buffer, BUFFER_SIZE, 0) >= 0);

    char file_name[FILE_NAME_MAX_SIZE + 1];
    memset(file_name, 0, FILE_NAME_MAX_SIZE + 1);
    strncpy(file_name, buffer, strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));  //长度取较短的
    std::cout << file_name;

    FILE *fp = fopen(file_name, "rb");  //以只读,二进制的方式打开一个文件
    assert(NULL != fp);
    memset(buffer, 0, BUFFER_SIZE);
    int length = 0;

    while ((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
    {
        assert(send(m_new_socket, buffer, length, 0) >= 0);
        memset(buffer, 0, BUFFER_SIZE);
    }
    fclose(fp);
    std::cout << "文件: " << file_name << std::endl << "发送成功 !" << std::endl;
    closesocket(m_new_socket);
    return 0;
}

主函数的调用如下:

int main()
{
    cout << "欢迎使用文件服务器" << endl
        << "请选择服务器的工作模式(输入数字)" << endl
        << "-->  0.客户端上传文件到本服务器" << endl
        << "-->  1.客户端从本服务器下载文件到本地" << endl
        << "-->  2.关闭程序" << endl;

    int choose = 0;
    cin >> choose;
    
    
    
    switch (choose)
    {
    case 0:
        cout << "设置服务器文件接收存放位置,例如输入'c:\\test\\'" << endl;
        cin >> upload_to_server_path;
        listenToUpload();
        break;
    case 1:
        listenToDownload();
        break;
    case 2:
        return 0;
    default:
        cout << "输入错误" << endl;
    }
    return 0;
}

以上就是传输文件的服务端的全部过程

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值