Send binary file over TCP/IP connection

前端 未结 2 1986
南方客
南方客 2020-12-06 04:17

I will rephrase the whole question here so that it is answerable.

I am able to copy binary file perfectly in the same machine not using sockets but just making a sim

2条回答
  •  长情又很酷
    2020-12-06 04:23

    You need to loop both the sending and receiving. Neither send() nor recv() are guaranteed to send/read as many bytes as you requested.

    You also should send the file size before the file data so the receiver knows how many bytes to expect and when to stop reading.

    Try something more like this:

    SERVER

    bool senddata(SOCKET sock, void *buf, int buflen)
    {
        unsigned char *pbuf = (unsigned char *) buf;
    
        while (buflen > 0)
        {
            int num = send(sock, pbuf, buflen, 0);
            if (num == SOCKET_ERROR)
            {
                if (WSAGetLastError() == WSAEWOULDBLOCK)
                {
                    // optional: use select() to check for timeout to fail the send
                    continue;
                }
                return false;
            }
    
            pbuf += num;
            buflen -= num;
        }
    
        return true;
    }
    
    bool sendlong(SOCKET sock, long value)
    {
        value = htonl(value);
        return senddata(sock, &value, sizeof(value));
    }
    
    bool sendfile(SOCKET sock, FILE *f)
    {
        fseek(f, 0, SEEK_END);
        long filesize = ftell(f);
        rewind(f);
        if (filesize == EOF)
            return false;
        if (!sendlong(sock, filesize))
            return false;
        if (filesize > 0)
        {
            char buffer[1024];
            do
            {
                size_t num = min(filesize, sizeof(buffer));
                num = fread(buffer, 1, num, f);
                if (num < 1)
                    return false;
                if (!senddata(sock, buffer, num, 0))
                    return false;
                filesize -= num;
            }
            while (filesize > 0);
        }
        return true;
    }
    

    FILE *filehandle = fopen("imagefile.jpg", "rb");
    if (filehandle != NULL)
    {
        sendfile(clientsocket, filehandle);
        fclose(filehandle);
    }
    

    CLIENT

    bool readdata(SOCKET sock, void *buf, int buflen)
    {
        unsigned char *pbuf = (unsigned char *) buf;
    
        while (buflen > 0)
        {
            int num = recv(sock, pbuf, buflen, 0);
            if (num == SOCKET_ERROR)
            {
                if (WSAGetLastError() == WSAEWOULDBLOCK)
                {
                    // optional: use select() to check for timeout to fail the read
                    continue;
                }
                return false;
            }
            else if (num == 0)
                return false;
    
            pbuf += num;
            buflen -= num;
        }
    
        return true;
    }
    
    bool readlong(SOCKET sock, long *value)
    {
        if (!readdata(sock, value, sizeof(value)))
            return false;
        *value = ntohl(*value);
        return true;
    }
    
    bool readfile(SOCKET sock, FILE *f)
    {
        long filesize;
        if (!readlong(sock, &filesize))
            return false;
        if (filesize > 0)
        {
            char buffer[1024];
            do
            {
                int num = min(filesize, sizeof(buffer));
                if (!readdata(sock, buffer, num))
                    return false;
                int offset = 0;
                do
                {
                    size_t written = fwrite(&buffer[offset], 1, num-offset, f);
                    if (written < 1)
                        return false;
                    offset += written;
                }
                while (offset < num);
                filesize -= num;
            }
            while (filesize > 0);
        }
        return true;
    }
    

    FILE *filehandle = fopen("imagefile.jpg", "wb");
    if (filehandle != NULL)
    {
        bool ok = readfile(clientsocket, filehandle);
        fclose(filehandle);
    
        if (ok)
        {
            // use file as needed...
        }
        else
            remove("imagefile.jpg");
    }
    

提交回复
热议问题