从套接字C发送和接收文件的问题

时间:2020-06-15 06:43:25

标签: c++ sockets mfc

im试图将文件从服务器发送到客户端 我的服务器上有此功能:

UINT CServerDlg::sendFile(WPARAM pParam)
{
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        return FALSE;
    }
    else {
        if (AfxSocketInit() == FALSE)
        {
            return FALSE;
        }

        CSocket ServerSocket;
        if (ServerSocket.Create(Dport, SOCK_STREAM, NULL) == 0)
        {
            return FALSE;
        }
        else
        {
            if (ServerSocket.Listen(32) == FALSE)
            {
                ServerSocket.Close();
                return FALSE;
            }

        }


        CSocket Connector;
        if (ServerSocket.Accept(Connector))
        {
            char* buffer = NULL;

            FILE* fi = fopen(file_name.c_str(), "rb");
            if (!fi)
                return 0;

            //get the file length
            fseek(fi, 0, SEEK_END);
            long file_size = ftell(fi);
            fseek(fi, 0, SEEK_SET);

            //send packet's length first and then send the packet
            //(one file includes multiple packets) and SIZE_BUFFER=4096
            int result=-1;
            int size = (file_size < SIZE_BUFFER) ? (int)file_size : SIZE_BUFFER;
            while (file_size >= (long long)SIZE_BUFFER) {
                fread(buffer, size, 1, fi);
                result = send(Connector, (char*)&file_size, sizeof(int), 0);

                if (result == SOCKET_ERROR) return 0;
                do { size = send(Connector,buffer, size, 0); } while (size == -1);

                memset(buffer, 0, SIZE_BUFFER);
                file_size = file_size - (long long)size;
            }
            if (file_size != 0) {
                if (send(Connector, (char*)&file_size, sizeof(int), 0) == SOCKET_ERROR) return 0;
                fread(buffer, file_size, 1, fi);
                do { size = send(Connector,buffer, file_size, 0); } while (size == -1);

            }

            delete[] buffer;
            fclose(fi);
        }
        else {
            return 0;
        }
        Connector.Close();
        ServerSocket.Close();
    }
    return 1;
}

我在客户端文件中得到了这个信息:

bool MainDlg::DownloadFile(char* file_name, int port) {
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        return FALSE;
    }
    //copy tu demo
    if (AfxSocketInit() == FALSE)
    {
        return FALSE;
    }

    CSocket ClientSocket;
    ClientSocket.Create();

    if (ClientSocket.Connect(_T("127.0.0.1"), port) != 0)
    {
        char* buffer = NULL;
        int size = 0;
        FILE* fo = fopen(file_name, "wb");
        recv(ClientSocket, (char*)&size, sizeof(int), 0);
        while (size >= SIZE_BUFFER) {
            do { size = recv(ClientSocket, (char*)buffer, SIZE_BUFFER, 0); } while (size == -1);

            fwrite((char*)buffer, size, 1, fo);
            memset(buffer, 0, SIZE_BUFFER);
            size = recv(ClientSocket, (char*)&size, sizeof(int), 0);
        }
        if ((size != SOCKET_ERROR)) size = recv(ClientSocket, (char*)buffer, size, 0);
        else return 0;
        delete[] buffer;
        fclose(fo);
    }
    else {
        return 0;
    }
    ClientSocket.Close();
    return 1;
}

服务器和客户端已连接,但似乎无法发送数据包。即使它无法发送,但执行文件也没有调用错误,但是当我调试时确实会发生错误。我在fread(buffer, file_size, 1, fi)遇到未知错误: Server.exe中0x00007FF6F17BDF28的未处理异常:将无效参数传递给认为无效参数致命的函数。

1 个答案:

答案 0 :(得分:2)

您必须为缓冲区分配内存,因为fread的第一个参数:

指向至少具有(size*count个字节大小的内存块的指针,该内存块将转换为void*

使用mallocnew

我建议使用std::array不必担心删除内存。