通过C中的套接字发送和接收文件

时间:2014-08-07 08:18:18

标签: c windows file sockets

我注意到有一个C ++和C#的内置函数,但是C没有。 (我在Windows机器上)。

所以我写了这两个函数,但它们没有工作,它们只是卡住了(我怀疑它是发送一个,因为当客户端接收时他只是根据函数返回值得到错误)。

以下是功能(服务器和客户端之间的套接字工作正常,我已经测试过了):

int recvFile(SOCKET s, const char* file_path)
{
    FILE* fp = fopen(file_path, "wb");
    char* file_buf = malloc(sizeof(char)*PACKAGE_LEN); //so it will be 0
    int bytesRecieved, bytesWritten;
    if(!fp)
    {
        fclose(fp);
        free(file_buf);
        return 1;
    }

    do
    {
        bytesRecieved = recv(s, file_buf, PACKAGE_LEN, 0); //receiving that file buffer in the size of PACKAGE_LEN (maximum chunk size). 
        if(bytesRecieved != PACKAGE_LEN)
        {
            fclose(fp);
            free(file_buf);
            return 1; //if there's an error...
        }
        if(!charPresent(file_buf, PACKAGE_LEN, EOF)) //as long as there's no EOF character in the file buffer received now.
        {
            fwrite(file_buf, sizeof(char), PACKAGE_LEN, fp); //write to file normally.
        }
    }
    while(!charPresent(file_buf, PACKAGE_LEN, EOF)); // do it as long there's no EOF in the file buffer.
    fwrite(file_buf, sizeof(char), indexOf(file_buf, PACKAGE_LEN, EOF), fp); //the last time you write the file buffer including the EOF is outside the loop.

    fclose(fp);
    free(file_buf);

    return 0;
}

int charPresent(const char* str, size_t size, char ch)
{
    int i;
    for(i = 0 ; i < size ; i++)
    {
        if(str[i] == ch)
        {
            return 1;
        }
    }

    return 0;
}

int indexOf(const char* str, size_t size, char ch)
{
    int i;
    for(i = 0 ; i < size ; i++)
    {
        if(str[i] == ch)
        {
            return i;
        }
    }

    return -1;
}

(在功能charPresent()IndexOf方面犯错的地方不多 - 我没有故意使用strlen(),因为\0不是答应在那个缓冲区里)。和...

int sendFile(SOCKET s, const char* file_path)
{
    FILE* fp = fopen(file_path, "rb");
    int i, err = 0, bytesSent, isOk = 1;
    char* file_buf = malloc(sizeof(char)*PACKAGE_LEN);
    char ch = 0;
    if(!fp)
    {
        fclose(fp);
        free(file_buf);
        return 1;
    }
    while(ch != EOF && isOk)
    {
        i = 0;
        do
        {
            do
            {
                err = ((fread(&ch, sizeof(char), 1, fp)) != 1);
                file_buf[i] = ch;
            }
            while(err); //keep reading until read successfully.
            i++;
            if(i == PACKAGE_LEN) //means we achieved the maximum chunk size.
            {
                isOk = 0; //to exit the inner loop.
            }
        }
        while(ch != EOF && isOk);
        bytesSent = send(s, file_buf, PACKAGE_LEN, 0); //sending the file buffer over the socket.
        if(bytesSent != PACKAGE_LEN)
        {
            fclose(fp);
            free(file_buf);
            return 1; //return an error (it is taken care of later on).
        }
        isOk = 1; // so the loop won't stop because we achieved only one chunk.
    }

    fclose(fp);
    free(file_buf);

    return 0;
}

我做错了什么? :P 我想到了一个替代方案,它只是为了找出文件的长度和循环FILE_LEN/PACKAGE_LEN + ((!(FILE_LEN%PACKAGE_LEN))?(0):(1))而在上一次运行中只发送一个带有EOF但是基本上它是相同的概念,我认为。

1 个答案:

答案 0 :(得分:2)

你的代码真的无法挽救。你应该诚实地重新开始。

在编写任何代码之前,请查看使用TCP的其他协议的某些协议规范。您可以查看FTP,HTTP,SMTP等。

特别注意他们如何划分邮件。请记住,TCP是一种字节流协议 - 它不会保留消息边界。

我强烈建议你去编写规范。这样,如果您的代码不起作用,您可以确定哪一方不符合规范。 (如果它们都是,并且它仍然无法工作,那么规范就会被破坏。)否则,没有办法弄清楚错误是什么,因为没有任何陈述。什么是对的。

此外,您无法以这种方式使用EOF。没有代表文件末尾的字符。每个可能的字符值都可以包含在文件中。没有&#34;额外&#34;可能意味着&#34;文件结尾的字符&​​#34;。