无法将图像从http服务器发送到客户端

时间:2016-06-08 10:01:35

标签: c linux http server

我正在用c代码实现一个简单的http服务器。 我通过firefox浏览器作为客户端连接到服务器,并写:

http://localhost:<port number>/<path to file>

现在,我尝试了一个简单的文本文件,它的工作原理。但是,当我尝试使用图像时,它不起作用。 重要的是要提到几天前它确实有效,但是由于我从TA获得的一些注释,我改变了我的代码,现在它不起作用......

我添加了一些辅助打印件并看到一些数据已发送,但是在某些时候它会卡住并且不再发送。 我的猜测是,不知何故发送缓冲区被填满了,但我确保在发送结束后它是空的...你能尝试找出问题所在吗?

#define BUF_SIZE 2048


int sendToClient(int clientFd, char *buf)
{
    int bytesSent;
    int totalSent = 0;
    size_t notSent = strlen(buf);
    while (notSent > 0)
    {
        if ((bytesSent = send(clientFd, buf + totalSent, notSent, 0)) < 0)
        {
            printf("send syscall failed: %s\n", strerror(errno));
            return -1;
        }
        notSent -= bytesSent;
        totalSent += bytesSent;
    }
    return totalSent;

}


void handleFile(int sockFd, char *path, struct stat *statBuf)
{
    //the stat structure pointer is delivered as a parameter, 
    //it already contains info about the file we want to send
    //sockFd is the client's socket file descriptor.
    //path is the path to the file...

    size_t totalBytesToSend = (size_t) statBuf->st_size;
    int fd = open(path, O_RDONLY, 0777);
    if (fd < 0)
    {
        printf("open syscall failed: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
    // sending some initial http stuff...
    char buf[BUF_SIZE];
    // zero buffer
    memset(buf, 0, BUF_SIZE);

    int bytesSent;    
    while (totalBytesToSend > 0)
    {   
        if (read(fd, buf, BUF_SIZE) < 0)
        {
            printf("read syscall failed: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
        //send buf to client
        if ((bytesSent = sendToClient(sockFd, buf)) < 0)
        {
            exit(EXIT_FAILURE);
        }
        // data was sent - zero buf again
        memset(buf, 0, BUF_SIZE);
        totalBytesToSend -= bytesSent;
    }
    //close file & socket
    close(fd);
    close(sockFd);
}

谢谢!

1 个答案:

答案 0 :(得分:2)

错误在于:size_t notSent = strlen(buf);。您假设缓冲区中的第一个空标记从文件读取的数据的结尾。对于永远不应包含空字节的文本文件有意义,但对于像图像文件这样的二进制文件,它是错误的假设。因为它们可以包含空字节,所以不会将从文件读取的所有字节传输到客户端,最坏的情况是缓冲区的第一个字节是0!

您必须将实际从磁盘读取的字节数传递给sendToClient函数并使用它。永远不要假设特定字节或序列永远不会出现在二进制文件中......