如何在winsock2中使用c发送图像

如何在winsock2中使用c发送图像,c,windows,visual-studio-2010,winsock2,C,Windows,Visual Studio 2010,Winsock2,我正在用c(winsock2)编写一个非常简单的Web服务器 我能够返回html页面的内容 目前,我正在做的是将文件内容写入char*缓冲区,并使用“send()”发送它 虽然当我尝试读取图像(jpg、bmp)时,我无法将字符写入缓冲区a,但某些字符为“null”(0) 如何发送整个图像文件 谢谢 根据您将映像加载到Web服务器的方式,您需要使用或,还需要将映像包装到适当的HTTP头中 请注意,这些是MS特定的扩展 另请参见您可以将空字符存储在char*缓冲区中。您只需使用计数器来记住写入的字符

我正在用c(winsock2)编写一个非常简单的Web服务器

我能够返回html页面的内容

目前,我正在做的是将文件内容写入char*缓冲区,并使用“send()”发送它

虽然当我尝试读取图像(jpg、bmp)时,我无法将字符写入缓冲区a,但某些字符为“null”(0)

如何发送整个图像文件


谢谢

根据您将映像加载到Web服务器的方式,您需要使用或,还需要将映像包装到适当的HTTP头中

请注意,这些是MS特定的扩展


另请参见您可以将空字符存储在
char*
缓冲区中。您只需使用计数器来记住写入的字符数,而不是通过计算非空字符数(可以是整数,也可以是指向缓冲区中下一个插入点的指针)来重新计算

要发送文件,您将执行以下操作:

int sendFile(int sock, const char* filename) {
    FILE* file = fopen(filename, "rb");
    if (file == NULL)
        return -1;

    if (fseek(file, 0, SEEK_END) != 0) {
        fclose(file);
        return -1;
    }

    off_t size = ftello(file);
    if (fseek(file, 0, SEEK_SET) != 0) {
        fclose(file);
        return -1;
    }

    if (SendBinaryFileHeaderAndSize(sock, size) < 0) {
        fclose(file);
        return -1;
    }

    char buffer[4096];
    for (;;) {
        size_t read = fread(buffer, 1, sizeof(buffer), file);
        if (read == 0) {
            int retcode = 0;
            if (ferror(file))
                retcode = -1;
            fclose(file);
            return retcode;
        }

        for (size_t sent = 0; sent < read;) {
            int ret = send(sock, buffer + sent, read - sent, 0);
            if (ret < 0) {
                fclose(file);
                return -1;
            }

            assert(ret <= read - sent);
            sent += ret;
        }
    }
}
int-sendFile(int-sock,const-char*filename){
FILE*FILE=fopen(文件名,“rb”);
if(file==NULL)
返回-1;
如果(fseek(文件,0,搜索结束)!=0){
fclose(文件);
返回-1;
}
off_t size=ftello(文件);
if(fseek(文件,0,搜索集)!=0){
fclose(文件);
返回-1;
}
if(SendBinaryFileHeaderAndSize(sock,size)<0){
fclose(文件);
返回-1;
}
字符缓冲区[4096];
对于(;;){
size\u t read=fread(buffer,1,sizeof(buffer),file);
如果(读==0){
int-retcode=0;
如果(ferror(文件))
retcode=-1;
fclose(文件);
返回代码;
}
对于(发送的大小=0;发送的<读取;){
int-ret=send(sock,buffer+sent,read-sent,0);
如果(ret<0){
fclose(文件);
返回-1;
}

assert(ret您需要了解send()和fread()的用法在缓冲区中工作.0s对于send或fread来说不是问题-它们不会将缓冲区解释为以null结尾的字符串。

你能给我一些我正在使用WindowsXP的传输包的示例代码吗?我对c不太熟悉。我建议你在阅读大部分内容时阅读所有内容。在传输文件方面找不到太多内容。你怎么做我知道c语言中图像文件的大小?一旦我知道我可以使用fgetc从图像中获取内容吗?而且,我想我是从fseek中获得大小的。但是当我在浏览器中打开图像时,浏览器只是一个空页面。里面什么都没有。你可以使用
fseek(file,O,SEEK_END)
,或者一些特定于平台的代码(
lstat
GetFileInformationByHandle
,…),以获取文件的大小。您还需要检查是否按照HTTP协议向客户端发送了正确的头(大小、内容类型…)(您可以使用另一个Web服务器检查在尝试访问二进制文件时发送的内容)。我似乎能够读取该文件。虽然当我打开它时,我能够下载该文件,但它显示已损坏。fgetc是否返回有符号字符?winsock.send是否允许传输无符号字符?对于二进制文件,您可能应该使用
fread
读取整个文件块,而不是使用
fgetc逐字节读取它
(这将更有效)。
send
函数不会解释缓冲区的内容,而是按原样传输,
fgetc
返回一个
int
(以便能够区分EOF和简单字符)。因此,在使用该值时必须小心,因为
char
已扩展为
int
,符号可能已被传播。非常感谢,是的,一个非常类似的代码对我起了作用。基本上我现在做的是,在发送所有字节之前传输3096字节的数据。谢谢。