简体   繁体   English

使用C中的套接字编程下载图像

[英]Downloading images using socket programming in C

I have a program which downloads the html file corresponding to the link given as an argument to the program. 我有一个程序可以下载与链接相对应的html文件,该链接是该程序的参数。 Next I am parsing the HTML file for images and downloading them using separate HTTP/1.0 connections and storing them in a file. 接下来,我将解析图像的HTML文件,并使用单独的HTTP / 1.0连接下载它们并将它们存储在文件中。 The problem I am facing is that after the file write is complete, the image cannot be opened by the image viewer. 我面临的问题是文件写入完成后,图像查看器无法打开图像。 Here is the function which downloads the image:: 这是下载图像的功能:

void getImg(char imgUrl[],char cwd[],char fileName[]){

struct addrinfo hints;          
struct addrinfo *serverInfo;                                        // will point to the results
int socket_desc;                                                    // socket Descriptor
int status;
char port[4]="80";

printf("\n---------------------------------------\ngetImg \n\timgUrl:: %s\n\tcwd:: %s\n\tfilename:: %s\n\n",imgUrl,cwd,fileName);

//-------------------------REQUEST ---------------------------------------------
char message[500] = "GET ";
char hostUrl[300];
char *temp;

if(imgUrl[0]!='/'){
    imgUrl=strstr(imgUrl,"/")+1;
    imgUrl=strstr(imgUrl,"/")+1;
    temp=imgUrl;
    imgUrl=strstr(imgUrl,"/");
    strncpy(hostUrl,temp,(imgUrl-temp));
    strcat(message,imgUrl);
}
else{
    strcpy(hostUrl,host);

    if(pageUrl!=NULL)
        strcat(message,pageUrl);
    else
        strcat(message,"/");
    strcat(message,imgUrl+1);
}

strcat(message," HTTP/1.0\r\nHost: ");
strcat(message,hostUrl);
strcat(message,"\r\n\r\n");
printf("\n\n--------------------------------\nGET REQUEST::\n%s\n",message);



//-------------------------FILE ---------------------------------------------
FILE *img;
strcat(cwd,fileName);
img=fopen(cwd,  "w+");
// HANDLE fileHandle = (HANDLE)_get_osfhandle(fileno(img));

//-------------------------SOCKETS ---------------------------------------------
memset(&hints, 0, sizeof hints);                                    // make sure the struct is empty
hints.ai_family = AF_INET;                                          // don't care IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM;                                    // TCP stream sockets

//-------------------------------------------------------------------GET ADDR INFO

status = getaddrinfo(hostUrl, port, &hints, &serverInfo);
if(status!=0){

    printf("Could Not Get AddrInfo Error:: %s\n",gai_strerror(status));
    exit(EXIT_FAILURE);
}

//------------------------------------------------------------------Create socket


socket_desc = socket(serverInfo->ai_family, serverInfo->ai_socktype, serverInfo->ai_protocol);
if (socket_desc == -1)
{
    printf("Could not create socket");
    exit(EXIT_FAILURE);
}


//------------------------------------------------------------------Connect to remote server using socket and server record

if (connect(socket_desc ,  serverInfo->ai_addr, serverInfo->ai_addrlen))
{
    printf("connect error");
    exit(EXIT_FAILURE);
}
printf("Connected \n---------\n");



if( send(socket_desc , message , strlen(message) , 0) < 0)
{
    printf("IMG Send failed :");
    exit(EXIT_FAILURE);
}
printf("IMG Data Sent\n");

//-------------------------------------------------------------------Receive a reply from the server
size_t rec_len=-1;
char reply[400], *replyStart;
replyStart=reply;
int headerFlag=1;
// printf("SIZE OF REPLY::%ld\n",sizeof(reply));
memset (reply, '\0', sizeof(reply));


printf("IMG REPLY:: \n");
while( (rec_len=recv(socket_desc,reply , sizeof(reply) -1, 0)) > 0){
    printf("\n%s\n",reply);
    if(headerFlag==1){
        if(strstr(reply,"HTTP/1.0 404 Not Found")!=NULL ){
            fclose(img);
            break;
        }
        replyStart=removeHeader(replyStart);
        assert(replyStart!=NULL);
    }

    if (img!=NULL)
    {   
        if(headerFlag==1){
            fwrite((void*)reply,sizeof(char),rec_len-(replyStart-reply),img);
            headerFlag=0;
        }
        else{
            fwrite((void*)reply,sizeof(char),rec_len,img);
        }
    }
    memset (reply, '\0', sizeof(reply));
}

if( rec_len==-1)
{
    printf("IMG Receive failed %s",strerror(errno));
    exit(EXIT_FAILURE);
}

fclose(img);
}



char* removeHeader(char *replyStart){
int i=0;
for(;i<12;i++){
    replyStart=strstr(replyStart,":")+1;
    assert(replyStart!=NULL);
}
replyStart=strstr(replyStart,"\n");

return replyStart;
}

您需要先阅读标题,直到获得空白行, 然后再开始复制图像数据。

Every image file has it's own signature. 每个图像文件都有其自己的签名。 For instance, the first eight bytes of a PNG datastream always contain the following (decimal) values: 137 80 78 71 13 10 26 10 I just had to find this stream in my response. 例如,PNG数据流的前八个字节始终包含以下(十进制)值:137 80 78 71 13 10 26 10我只需要在响应中找到该流。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM