Winsock将文件上传到远程服务器

时间:2015-01-08 02:19:23

标签: c++ winsock

我正在尝试将文件上传到服务器,但它们总是被破坏,程序非常简单,只用于在客户端和服务器之间传输文件。 我需要在此代码中提供帮助,以解决问题。 并改善它。

服务器

    int Socket_Manip::FILE_UPLOAD() {

    //get file size.
    iResult = recv(ClientSocket, GotFileSize, LENGTH, 0);
    if (iResult == 0)
    {
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }
    else if (iResult < 0) {
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }

    //start manip download
    long FileSize = atoi(GotFileSize);
    long SizeCheck = 0;
    char* mfcc;

    FILE *fp = fopen("C::\\Users\\Server\\Downloads\\transfer.zip", "wb");
    if (fp == NULL)
    {
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }
    if (FileSize > 1499) {
        mfcc = (char*)malloc(1500);
        while (FileSize > SizeCheck){
            int Received = recv(ClientSocket, mfcc, 1500, 0);
            if (Received == 0)
            {
                break;
            }
            else if (Received < 0) {
                closesocket(ClientSocket);
                WSACleanup();
                return 1;
            }
            SizeCheck += Received;
            fwrite(mfcc, 1, Received, fp);
            fflush(fp);
        }
    } else 
    {
        mfcc = (char*)malloc(FileSize + 1);
        int Received = recv(ClientSocket, mfcc, FileSize, 0);
        fwrite(mfcc, 1, Received, fp);
        fflush(fp);
    }

    fclose(fp);
    free(mfcc);

}

客户发送者

int File_Transfer_Manip() {
    FILE *File;
    char *Buffer;
    unsigned long Size;


    File = fopen("C:\\Users\\r4minux\\Downloads\\upload.zip", "rb");
    if (!File)
    {
        printf("Error file\n");
        return 1;
    }

    fseek(File, 0, SEEK_END);
    Size = ftell(File);
    fseek(File, 0, SEEK_SET);

    Buffer = new char[Size];

    fread(Buffer, Size, 1, File);
    char cSize[MAX_PATH];
    sprintf(cSize, "%i", Size);

    fclose(File);
    iResult = send(ConnectSocket, cSize, MAX_PATH, 0); // File size
    if (iResult == SOCKET_ERROR) {
        printf("send erroR: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        getchar();
        return 1;
    }

    int Offset = 0;
    while (Offset < Size)
    {
        int Amount = send(ConnectSocket, Buffer + Offset, Size - Offset, 0);
        if (Amount <= 0)
        {
            std::cout << "Error: " << WSAGetLastError() << std::endl;
            break;
        }
        else
        {
            Offset += Amount;
        }
    }

    // cleanup
    free(Buffer);

}

1 个答案:

答案 0 :(得分:2)

TCP是一个字节流。它没有消息边界的概念。您不确定send()实际上是在发送您提供的所有内容,还是recv()正在阅读您要求的所有内容。它们 CAN 返回更少的字节。你必须考虑到这一点。

请改为尝试:

SERVER:

int readBytes(SOCKET s, void *buffer, int buflen)
{
    int total = 0;

    unsigned char *pbuf = (unsigned char*) buffer;
    while (buflen > 0)
    {
        int iResult = recv(s, pbuf, buflen, 0);
        if (iResult < 0)
        {
            if (WSAGetLastError() == WSAEWOULDBLOCK)
            {
                // optionally use select() to wait for the
                // socket to have more bytes to read before
                // calling recv() again...
                continue;
            }

            printf("recv error: %d\n", WSAGetLastError());
            return SOCKET_ERROR;
        }
        else if (iResult == 0)
        {
            printf("disconnected\n");
            return 0;
        }
        else
        {
            pbuf += iResult;
            buflen -= iResult;
            total += iResult;
        }
    }

    return total;
}

int Socket_Manip::FILE_UPLOAD()
{
    //start download

    FILE *fp = fopen("C::\\Users\\Server\\Downloads\\transfer.zip", "wb");
    if (fp == NULL)
    {
        printf("Error creating file\n");
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }

    //get file size.
    unsigned long FileSize;
    int iResult = readBytes(ClientSocket, &FileSize, sizeof(FileSize));
    if (iResult <= 0)
    {
        fclose(fp);
        closesocket(ClientSocket);
        WSACleanup();
        return 1;
    }
    FileSize = ntohl(FileSize);

    char mfcc[1024];
    while (FileSize > 0)
    {
        int Received = readBytes(ClientSocket, mfcc, min(sizeof(mfcc), FileSize));
        if (Received <= 0)
        {
            fclose(fp);
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }

        if (fwrite(mfcc, 1, Received, fp) != Received)
        {
            printf("Error writing file\n");
            fclose(fp);
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }

        FileSize -= Received;
    }

    fflush(fp);
    fclose(fp);

    return 0;
}

客户端

int sendBytes(SOCKET s, void *buffer, int buflen)
{
    int total = 0;

    unsigned char *pbuf = (unsigned char*) buffer;
    while (buflen > 0)
    {
        int iResult = send(s, pbuf, buflen, 0);
        if (iResult < 0)
        {
            if (WSAGetLastError() == WSAEWOULDBLOCK)
            {
                // optionally use select() to wait for the
                // socket to have more space to write before
                // calling send() again...
                continue;
            }

            printf("send error: %d\n", WSAGetLastError());
            return SOCKET_ERROR;
        }
        else if (iResult == 0)
        {
            printf("disconnected\n");
            return 0;
        }
        else
        {
            pbuf += iResult;
            buflen -= iResult;
            total += iResult;
        }
    }

    return total;
}

int File_Transfer_Manip()
{
    char Buffer[1024];

    FILE *fp = fopen("C:\\Users\\r4minux\\Downloads\\upload.zip", "rb");
    if (!fp)
    {
        printf("Error opening file\n");
        return 1;
    }

    fseek(fp, 0, SEEK_END);
    unsigned long FileSize = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    unsigned long tmpFileSize = htonl(FileSize);
    int iResult = sendBytes(ConnectSocket, &tmpFileSize, sizeof(tmpFileSize));
    if (iResult <= 0)
    {
        fclose(fp);
        closesocket(ConnectSocket);
        WSACleanup();
        getchar();
        return 1;
    }

    while (FileSize > 0)
    {
        long Size = fread(Buffer, 1, min(sizeof(Buffer), FileSize), fp);
        if (Size <= 0)
        {
            printf("Error reading file\n");
            fclose(fp);
            closesocket(ConnectSocket);
            WSACleanup();
            getchar();
            return 1;
        }

        if (sendBytes(ConnectSocket, Buffer, Size) != Size)
        {
            fclose(fp);
            closesocket(ConnectSocket);
            WSACleanup();
            getchar();
            return 1;
        }

        FileSize -= Size;
    }

    fclose(fp);
    return 0;
}