C- Socket : Programming a Client/Server-Application to send a file

允我心安 提交于 2019-12-07 14:28:11

问题


I want to program an application to send a file with sockets:

Here my Server:

   void str_server(int sock)
    {
            char buf[1025];
            const char* filename="test.text";
            FILE *file = fopen(filename, "rb");
            err_abort("Test");
            while (!feof(file))
            {
                int rval = fread(buf, 1, sizeof(buf), file);
                send(sock, buf, rval, 0);
            }
    }

and here my client:

void RecvFile(int sock, const char* filename)
{
    int rval;
    char buf[0x1000];
    FILE *file = fopen(filename, "wb");
    while ((rval = recv(sock, buf, sizeof(buf), 0)) > 0)
    {
        fwrite(buf, 1, rval, file);
    }
    close(sock);
}

My problem is that my client create a file....but dont write the content in the file!


回答1:


Add some error handling to your code, that should help you track down the problem. Also note that send(), recv(), fread() and fwrite() are not guaranteed to write/read the entire buffer you specify, so you should take that into account as well.

Also, since TCP is a byte stream, the server needs to indicate when the file ends so the client knows when to stop reading. If you don't send the file size before sending the actual file, the only option is to close the socket when the transfer is done.

Try something like this:

int send_all(int sock, const void *buf, int len)
{
    const char *pbuf = (const char *) buf;

    while (len > 0)
    {
        int sent = send(sock, pbuf, len, 0);
        if (sent < 1)
        {
            // if the socket is non-blocking, then check
            // the socket error for WSAEWOULDBLOCK/EAGAIN
            // (depending on platform) and if true then
            // use select() to wait for a small period of
            // time to see if the socket becomes writable
            // again before failing the transfer...

            printf("Can't write to socket");
            return -1;
        }

        pbuf += sent;
        len -= sent;
    }

    return 0;
}

void str_server(int sock) 
{ 
    char buf[0x1000]; 
    const char* filename = "test.text";
    struct stat s;

    if (stat(filename, &s) == -1)
    {
        printf("Can't get file info"); 
        return;
    }

    FILE *file = fopen(filename, "rb"); 
    if (!file)
    {
        printf("Can't open file for reading"); 
        return;
    }

    // if you need to handle files > 2GB,
    // be sure to use a 64bit integer, and
    // a host-to-network function that can
    // handle 64bit integers...
    long size = s.st_size;
    long tmp_size = htonl(size);
    if (send_all(sock, &tmp_size, sizeof(tmp_size)) == 0)
    {
        while (size > 0)
        { 
            int rval = fread(buf, 1, min(sizeof(buf), size), file); 
            if (rval < 1)
            {
                printf("Can't read from file");
                break;
            }

            if (send_all(sock, buf, rval) == -1)
                break;

            size -= rval;
        }
    }

    fclose(file);
} 

int write_all(FILE *file, const void *buf, int len)
{
    const char *pbuf = (const char *) buf;

    while (len > 0)
    {
        int written = fwrite(pbuf, 1, len, file);
        if (written < 1)
        {
            printf("Can't write to file");
            return -1;
        }

        pbuf += written;
        len -= written;
    }

    return 0;
}

int read_all(int sock, void *buf, int len)
{
    char *pbuf = (char *) buf;
    int total = 0;

    while (len > 0)
    {
        int rval = recv(sock, pbuf, len, 0);
        if (rval < 0)
        {
            // if the socket is non-blocking, then check
            // the socket error for WSAEWOULDBLOCK/EAGAIN
            // (depending on platform) and if true then
            // use select() to wait for a small period of
            // time to see if the socket becomes readable
            // again before failing the transfer...

            printf("Can't read from socket");
            return -1;
        }

        if (rval == 0)
        {
            printf("Socket disconnected")
            return 0;
        } 

        pbuf += rval;
        len -= rval;
        total += rval;
    }

    return total;
}

void RecvFile(int sock, const char* filename) 
{ 
    int rval; 
    char buf[0x1000];

    FILE *file = fopen(filename, "wb"); 
    if (!file)
    {
        printf("Can't open file for writing");
        return;
    }

    // if you need to handle files > 2GB,
    // be sure to use a 64bit integer, and
    // a network-to-host function that can
    // handle 64bit integers...
    long size = 0;
    if (read_all(sock, &size, sizeof(size)) == 1)
    {
        size = ntohl(size);
        while (size > 0)
        {
            rval = read_all(sock, buf, min(sizeof(buf), size));
            if (rval < 1)
                break;

            if (write_all(file, buf, rval) == -1)
                break;
        } 
    }

    fclose(file); 
} 


来源:https://stackoverflow.com/questions/9875735/c-socket-programming-a-client-server-application-to-send-a-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!