如何在客户端服务器应用程序中正确发送文件?

时间:2019-03-10 11:16:24

标签: c windows client send

我想在客户端可以注册,登录,向其他客户端广播消息,发送文件等时创建客户端服务器应用程序。除了发送文件外,其他所有东西都运行良好。

在客户端应用程序中,我为要发送的每个文件创建了一个单独的线程。读取文件成功,但是发送效果不佳。我应该在服务器项目中创建一个线程来接收客户端发送的字节吗?

我希望发送文件是异步的,以便在服务器接收文件时另一个客户端可以与服务器通信。 用于读取文件并将数据发送到服务器的线程:

DWORD WINAPI SendFile(LPVOID param)
{
    FileStruct* fileStruct = (FileStruct*)param;
    CM_DATA_BUFFER* dataToSend = NULL;
    CM_SIZE dataToSendSize = MAXLENGTH;
    CM_ERROR error;
    CM_SIZE sendBytesCount = 0;
    FILE* f = fopen(fileStruct->filePath, "rb");
    char buffer[2];
    fseek(f, 0, SEEK_SET);
    if (f == NULL)
    {
        perror((const char*)f);
    }
    char messageBuffer[10];
    while (fread(buffer, 1, 1, f) == 1)
    {
        *(int*)messageBuffer = SENDTYPE;
        messageBuffer[4] = buffer[0];
        messageBuffer[5] = 0;

        dataToSend = NULL;
        error = CreateDataBuffer(&dataToSend, dataToSendSize);
        if (CM_IS_ERROR(error))
        {
            _tprintf_s(TEXT("Failed to create SEND data buffer with err-code=0x%X!\n"), error);
            DestroyClient(fileStruct->client);
            UninitCommunicationModule();
            return (DWORD)-1;
        }

        error = CopyDataIntoBuffer(dataToSend, (const CM_BYTE*)messageBuffer, (CM_SIZE)strlen(messageBuffer));
        if (CM_IS_ERROR(error))
        {
            _tprintf_s(TEXT("CopyDataIntoBuffer failed with err-code=0x%X!\n"), error);
            DestroyDataBuffer(dataToSend);
            DestroyClient(fileStruct->client);
            UninitCommunicationModule();
            return (DWORD)-1;
        }
        error = SendDataToServer(fileStruct->client, dataToSend, &sendBytesCount);
        if (CM_IS_ERROR(error))
        {
            _tprintf_s(TEXT("SendDataToServer failed with err-code=0x%X!\n"), error);
            DestroyDataBuffer(dataToSend);
            DestroyClient(fileStruct->client);
            UninitCommunicationModule();
            return (DWORD)-1;
        }
        DestroyDataBuffer(dataToSend);
    }
    return (DWORD)0;

}

这是Thread Server负责接收数据的代码的一部分:

while ((error = ReceiveDataFromClient(newClient, receivedData, &numberOfBytesRead)) == 0)
    {
        message = (char*)receivedData->DataBuffer;
        if (CM_IS_ERROR(error))
        {
            _tprintf_s(TEXT("ReceiveDataFormServer failed with err-code=0x%X!\n"), error);
            DestroyDataBuffer(sendData);
            DestroyDataBuffer(receivedData);
            break;
        }
        type = *(int*)receivedData->DataBuffer;
        printf("%x\n", type);
        if (type == SENDTYPE)
        {
            printf("%c", (char)receivedData->DataBuffer[4]);
            DestroyDataBuffer(receivedData);
            receivedData = NULL;
            error = CreateDataBuffer(&receivedData, MAXLENGTH);
            if (CM_IS_ERROR(error))
            {
                _tprintf_s(TEXT("Creating receivedDataBuffer failed with err-code =0x%X!\n"), error);
                UninitCommunicationModule();
            }
            continue;
        }

这是ReceiveDataFromClient函数:

CM_ERROR ReceiveDataFromClient(CM_SERVER_CLIENT* Client, CM_DATA_BUFFER* DataBufferToReceive, CM_SIZE* SuccessfullyReceivedBytesCount)
{
    if (Client == NULL || DataBufferToReceive == NULL || SuccessfullyReceivedBytesCount == NULL)
        return CM_INVALID_PARAMETER;

    CM_ERROR error = ReceiveData(
        Client->ClientConnection
        , DataBufferToReceive->DataBuffer
        , DataBufferToReceive->DataBufferSize
        , SuccessfullyReceivedBytesCount
    );
    if (CM_IS_ERROR(error))
        return error;

    DataBufferToReceive->UsedBufferSize = *SuccessfullyReceivedBytesCount;

    return error;
} 

这是ReceiveData函数:

CM_ERROR ReceiveData(CM_CONNECTION* Connection, CM_BYTE* OutputDataBuffer, CM_SIZE OutputDataBufferSize, CM_SIZE* SuccessfullyReceivedBytesCount)
{
    if (Connection == NULL)
        return CM_INVALID_CONNECTION;

    if (INVALID_SOCKET == Connection->ConnectionSocket)
        return CM_INVALID_PARAMETER;

    int receiveResult = recv(Connection->ConnectionSocket, (char*) OutputDataBuffer, OutputDataBufferSize, 0);
    if (receiveResult == SOCKET_ERROR)
    {
        CM_LOG_ERROR(TEXT("recv failed with err-code=0x%X!"), WSAGetLastError());
        return CM_CONNECTION_RECEIVE_FAILED;
    }

    if (receiveResult == 0)
        return CM_CONNECTION_TERMINATED;

    *SuccessfullyReceivedBytesCount = (CM_SIZE)receiveResult;

    return CM_SUCCESS;
}

0 个答案:

没有答案