通过流套接字发送图像

时间:2010-09-11 05:02:34

标签: c sockets tcp transactions

有人能指导我是否有一种特殊的方式在tcp套接字上发送图像(特别是.jpeg文件)?到目前为止,我正在开发一个似乎能很好地发送所有文本数据的网络服务器。当谈到jpeg图像时,会发送标题,Cygwin控制台在发送实际数据时会冻结。

我发送数据的方式是首先打开文件,将数据读入缓冲区,然后将其推送。有什么建议吗?

    while(!feof(sendFile)){

            bzero(send_buffer,sizeof(send_buffer));
            result = fread (send_buffer,1,sizeof(send_buffer),sendFile);

            while(result>0){
                result = fread (send_buffer,1,sizeof(send_buffer),sendFile);

                if(ferror(sendFile)){
                    printf("Error reading file: %s\n",request_page);
                }
                if((test=send(new_fd,send_buffer,sizeof(send_buffer),0))<0){
                    printf("Send returned %d\n",test);
                    printf("Sending %s Failed\n", request_page);
                    exit(1);
                }
                bzero(send_buffer,sizeof(send_buffer));
            }
        }
        fclose(sendFile);

2 个答案:

答案 0 :(得分:1)

使用此代码有几个错误或可能有错误。

result = fread (send_buffer,1,Fsize,sendFile);

此行从FsizesendFile读取send_buffer个字节。现在,我没有看到你从哪里得到Fsize,但鉴于它的名字,我猜它是文件的大小。您是否确保send_buffer足够大以容纳Fsize个字节?如果没有,你可能会在这里遇到潜在的缓冲区溢出,这会导致随机数据写入堆栈,从而导致各种麻烦。你可能想要阅读sizeof(send_buffer)。你似乎也有一个常数MAX_MSG。这是否等于发送缓冲区的大小?如果没有,那条线也会有问题。通常,您应该尝试使用一种一致的方法来引用此缓冲区的大小,这样您就不会被两个不同的值混淆并导致问题。

接下来,您尝试测试读取文件的错误:

if(result != Fsize && (result!=0)) {
printf("Reading error"); 
exit (1);
}

现在,我们来看看fread Fsize所说的内容:

  

fread()和fwrite()返回数字   成功读取或写入的项目   (即,不是字符数)。   如果发生错误,或文件结束   到达时,返回值为a   短项目数(或零)。

     

fread()不区分   文件结束和错误,以及来电者   必须使用feof(3)和ferror(3)来   确定发生了什么。

如果您没有确切的feof或零项,则会抛出错误。现在,根据文档,您可以在错误或文件结尾的情况下使用短计数或零。为了区分您是否需要提前退出循环或因错误而死亡,您需要致电ferror和/或{{1}}。

我猜你的错误在于上面提到的缓冲区溢出,但我建议修复这两个问题。

答案 1 :(得分:1)

你遇到的一个主要逻辑缺陷就是你多次调用fread()。你调用它一次,然后在调用send()之前再次调用它覆盖你需要发送的前一个缓冲区

在阅读下一个缓冲区之前,您也没有检查以确保send()实际发送完整缓冲区。当你只发送fread()实际读取的字节数时,你正在发送整个缓冲区。

请改为尝试:

unsigned char send_buffer[...];
bool error = false;

while (!feof(sendFile) && !error)
{ 
    bzero(send_buffer, sizeof(send_buffer)); 

    result = fread(send_buffer, 1, sizeof(send_buffer), sendFile);
    if (result < 1)
    {
        if (ferror(sendFile))
        {
            printf("Error reading file: %s\n", request_page); 
            error = true;
        }
        break;
    } 

    unsigned char *send_buffer_ptr = send_buffer;
    do
    {
        test = send(new_fd, send_buffer_ptr, result, 0);
        if (test <= 0)
        { 
            printf("Send returned %d\n", test); 
            printf("Sending %s Failed\n", request_page); 
            error = true;
            break; 
        } 

        send_buffer_ptr += test;
        result -= test;
    }
    while (result > 0);
}

fclose(sendFile); 

if (error)
    exit(1);