2017-02-28 42 views
0

我试图通过套接字将所有类型的文件发送到C++中的浏览器。我能够发送。 txt.html文件通过套接字很好,但是当我尝试发送JPEG时,出现错误The image "localhost:8199/img.jpg" cannot be displayed because it contains errors。我不知道为什么我的程序可以正常发送文本文件,但无法处理图像。这是我读文件,并将其写入到客户端:当在C++中通过套接字发送图像时,“图像无法显示错误”

int fileLength = read(in, buf, BUFSIZE); 
    buf[fileLength] = 0; 
    char *fileContents = buf; 

    while (fileLength > 0) { 

     string msg = "HTTP/1.0 200 OK\r\nContent-Type:" + fileExt + "\r\n\r\n\r\nHere is response data"; 
     int bytes_written; 

     if(vrsn == "1.1" || vrsn == "1.0"){ 
      write(fd, msg.c_str(), strlen(msg.c_str()));  
      bytes_written = write(fd, fileContents, fileLength); 
     } else { 
      bytes_written = write(fd, fileContents, fileLength); 
     } 

     fileLength -= bytes_written; 
     fileContents += bytes_written; 
    } 

全部代码是在这里:http://pastebin.com/vU9N0gRi

如果我查一下我的浏览器的网络控制台响应报头,我看到Content-Typeimage/jpeg所以我不确定我做错了什么。

图像文件的处理方式与普通文本文件不同吗?如果是这样,为了处理将图像文件发送到浏览器,我必须做些什么?

+1

损坏头和坏的长度(图片不是字符串)。 –

回答

3

string msg =“HTTP/1.0 200 OK \ r \ nContent-Type:”+ fileExt +“\ r \ n \ r \ n \ r \ n这里是响应数据。

这是对二进制数据(如图像)无效的HTTP响应。在HTTP头尾部\r\n\r\n终止后,之后的所有内容都是消息正文数据。所以,你发送\r\nHere is response data作为你的图像的头几个字节,破坏它们。您需要将其完全删除,即使对于您的txthtml文件也是如此。

更糟的是,你在每次循环发送msg,所以你的文件数据的每一个缓冲区前与您的HTTP响应字符串,彻底破坏进一步的图像数据。

此外,您的回复缺少Content-LengthConnection: close响应标头。

尝试一些更喜欢这个:

int sendRaw(int fd, const void *buf, int buflen) 
{ 
    const char *pbuf = static_cast<const char*>(buf); 
    int bytes_written; 

    while (buflen > 0) { 
     bytes_written = write(fd, pbuf, buflen); 
     if (written == -1) return -1; 
     pbuf += bytes_written; 
     buflen -= bytes_written; 
    } 

    return 0; 
} 

int sendStr(int fd, const string &s) 
{ 
    return sendRaw(fd, s.c_str(), s.length()); 
} 

... 

struct stat s; 
fstat(in, &s); 
off_t fileLength = s.st_size; 

char buf[BUFSIZE]; 
int bytes_read, bytes_written; 

if ((vrsn == "1.1") || (vrsn == "1.0")) { 
    ostringstream msg; 
    msg << "HTTP/1.0 200 OK\r\n" 
     << "Content-Type:" << fileExt << "\r\n" 
     << "Content-Length: " << fileLength << "\r\n" 
     << "Connection: close\r\n" 
     << "\r\n"; 
    sendStr(fd, msg.str()); 
} 

while (fileLength > 0) { 
    bytes_read = read(in, buf, min(fileLength, BUFSIZE)); 
    if (bytes_read <= 0) break; 
    if (sendRaw(fd, buf, bytes_read) == -1) break; 
    fileLength -= bytes_read; 
} 

close(fd); 
2

write(fd, msg.c_str(), strlen(msg.c_str())); - 你认为图像可能包含空(零)字节?所以把它当作C风格的字符串并不是一个好主意。

您应该发送您的原始数据并写入该数据的大小 - 即而不是,直到第一个空字节为止。

+0

原始数据不是由这一行发送的:'bytes_written = write(fd,fileContents,fileLength);'? –

+0

'vrsn'是一个字符串。它是HTTP/1.1字符串的1.1部分。 –

+1

@MahmudAdam:你发送的HTTP响应都是错误的。看到我的答案。 –

相关问题