linux c 实现 http post的代码-1

来源:互联网 发布:nginx设置根目录 编辑:程序博客网 时间:2024/06/03 04:02


需要在开发板上实现以http的协议上传图片的功能。


参考了以下作者的文章:

http://www.cnblogs.com/linbc/archive/2009/03/21/1400108.html

http://blog.csdn.net/sjin_1314/article/details/41776679

http://www.xuebuyuan.com/989667.html

http://blog.csdn.net/chinazgr/article/details/8244840


以及:

https://www.ietf.org/rfc/rfc1867.txt对于multipart/form-data的说明案例:

6. Examples   Suppose the server supplies the following HTML:     <FORM ACTION="http://server.dom/cgi/handle"           ENCTYPE="multipart/form-data"           METHOD=POST>     What is your name? <INPUT TYPE=TEXT NAME=submitter>     What files are you sending? <INPUT TYPE=FILE NAME=pics>     </FORM>   and the user types "Joe Blow" in the name field, and selects a text   file "file1.txt" for the answer to 'What files are you sending?'   The client might send back the following data:        Content-type: multipart/form-data, boundary=AaB03x        --AaB03x        content-disposition: form-data; name="field1"        Joe Blow        --AaB03x        content-disposition: form-data; name="pics"; filename="file1.txt"        Content-Type: text/plain         ... contents of file1.txt ...        --AaB03x--   If the user also indicated an image file "file2.gif" for the answer   to 'What files are you sending?', the client might client might send   back the following data:        Content-type: multipart/form-data, boundary=AaB03x        --AaB03x        content-disposition: form-data; name="field1"        Joe Blow        --AaB03x        content-disposition: form-data; name="pics"        Content-type: multipart/mixed, boundary=BbC04y        --BbC04y        Content-disposition: attachment; filename="file1.txt"        Content-Type: text/plain        ... contents of file1.txt ...        --BbC04y        Content-disposition: attachment; filename="file2.gif"        Content-type: image/gif        Content-Transfer-Encoding: binary          ...contents of file2.gif...        --BbC04y--        --AaB03x--


其中对于http://www.cnblogs.com/linbc/archive/2009/03/21/1400108.html文章里的代码我基本上全拿过来用了,谢谢原作者!


文件如下:

tuobao_tcpclient.h

#ifndef _TUOBAO_TCP_CLIENT_#define _TUOBAO_TCP_CLIENT_#include <netinet/in.h>#include <sys/socket.h>typedef struct _tuobao_tcpclient{    int socket;    int remote_port;    char remote_ip[16];    struct sockaddr_in _addr;    int connected;} tuobao_tcpclient;int tuobao_tcpclient_create(tuobao_tcpclient *,const char *host, int port);int tuobao_tcpclient_conn(tuobao_tcpclient *);int tuobao_tcpclient_recv(tuobao_tcpclient *,char **lpbuff,int size);int tuobao_tcpclient_send(tuobao_tcpclient *,char *buff,int size);int tuobao_tcpclient_close(tuobao_tcpclient *);#endif



tuobao_tcpclient.c

#include <stdio.h>#include <stdlib.h>#include <arpa/inet.h>#include <netdb.h>#include "tuobao_tcpclient.h"#define BUFFER_SIZE 1024int tuobao_tcpclient_create(tuobao_tcpclient *pclient,const char *host, int port){    struct hostent *he;    if(pclient == NULL) return -1;    memset(pclient,0,sizeof(tuobao_tcpclient));    if((he = gethostbyname(host))==NULL){        return -2;    }    pclient->remote_port = port;    strcpy(pclient->remote_ip,inet_ntoa( *((struct in_addr *)he->h_addr) ));    pclient->_addr.sin_family = AF_INET;    pclient->_addr.sin_port = htons(pclient->remote_port);    pclient->_addr.sin_addr = *((struct in_addr *)he->h_addr);    if((pclient->socket = socket(AF_INET,SOCK_STREAM,0))==-1){        return -3;    }    /*TODO:是否应该释放内存呢?*/    return 0;}int tuobao_tcpclient_conn(tuobao_tcpclient *pclient){    if(pclient->connected)        return 1;    if(connect(pclient->socket, (struct sockaddr *)&pclient->_addr,sizeof(struct sockaddr))==-1){        return -1;    }    pclient->connected = 1;    return 0;}int tuobao_tcpclient_recv(tuobao_tcpclient *pclient,char **lpbuff,int size){    int recvnum=0,tmpres=0;    char buff[BUFFER_SIZE];    *lpbuff = NULL;    while(recvnum < size || size==0){        tmpres = recv(pclient->socket, buff,BUFFER_SIZE,0);        if(tmpres <= 0)            break;        recvnum += tmpres;        if(*lpbuff == NULL){            *lpbuff = (char*)malloc(recvnum);            if(*lpbuff == NULL)                return -2;        }else{            *lpbuff = (char*)realloc(*lpbuff,recvnum);            if(*lpbuff == NULL)                return -2;        }        memcpy(*lpbuff+recvnum-tmpres,buff,tmpres);    }    return recvnum;}int tuobao_tcpclient_send(tuobao_tcpclient *pclient,char *buff,int size){    int sent=0,tmpres=0;    while(sent < size){        tmpres = send(pclient->socket,buff+sent,size-sent,0);        if(tmpres == -1){            return -1;        }        sent += tmpres;    }    return sent;}int tuobao_tcpclient_close(tuobao_tcpclient *pclient){    close(pclient->socket);    pclient->connected = 0;}


httppost.c

#include "tuobao_tcpclient.h"#include <stdio.h>#include <string.h>#include <fcntl.h>#include <sys/stat.h>void http_post_file(tuobao_tcpclient *pclient,char *page,char *filepath,char **response){//check if the file is valid or notstruct stat stat_buf;if(lstat(filepath,&stat_buf)<0){printf("lstat %s fail\n");return;}if(!S_ISREG(stat_buf.st_mode)){printf("%s is not a regular file!\n",filepath);return ;}char *filename;filename=strrchr(filepath,'/');if(filename==NULL){}filename+=1;if(filename>=filepath+strlen(filepath)){//'/' is the last characterprintf("%s is not a correct file!\n",filepath);return ;}printf("filepath=%s,filename=%s\n",filepath,filename);char content_type[2048];memset(content_type, 0, 2048);char post[300],host[100],content_len[100];char *lpbuf,*ptmp;int len=0;lpbuf = NULL;const char *header2="User-Agent: Is Http 1.1\r\nCache-Control: no-cache\r\nAccept: */*\r\n";sprintf(post,"POST %s HTTP/1.1\r\n",page);sprintf(host,"HOST: %s:%d\r\n",pclient->remote_ip,pclient->remote_port);strcpy(content_type,post);strcat(content_type,host);char *boundary = (char *)"---------------------------41184676334";strcat(content_type, "Content-Type: multipart/form-data; boundary=");strcat(content_type, boundary);strcat(content_type, "\r\n");//--Construct request data {filePath, file}char content_before[4096];memset(content_before, 0, 4096);strcat(content_before, "--");strcat(content_before, boundary);strcat(content_before, "\r\n");strcat(content_before, "Content-Disposition: form-data; name=\"filePath\"\r\n\r\n");strcat(content_before, filepath);strcat(content_before, "\r\n");strcat(content_before, "--");strcat(content_before, boundary);strcat(content_before, "\r\n");strcat(content_before, "Content-Disposition: attachment; name=\"userfile\"; filename=\"");strcat(content_before, filename);strcat(content_before, "\"\r\n");strcat(content_before, "Content-Type: image/jpeg\r\n\r\n");//strcat(content_before, "Content-Type: image/jpeg\r\n\r\n");char content_end[1024];memset(content_end, 0, 1024);strcat(content_end, "\r\n");strcat(content_end, "--");strcat(content_end, boundary);strcat(content_end, "--\r\n");int max_cont_len=5*1024*1024;char content[max_cont_len];int fd;fd=open(filepath,O_RDONLY,0666);if(!fd){printf("fail to open file : %s\n",filepath);return;}len=read(fd,content,max_cont_len);close(fd);char *lenstr;lenstr = (char*)malloc(128);sprintf(lenstr, "%d", (strlen(content_before)+len+strlen(content_end)));strcat(content_type, "Content-Length: ");strcat(content_type, lenstr);strcat(content_type, "\r\n\r\n");//sendif(!pclient->connected){tuobao_tcpclient_conn(pclient);}//content-typetuobao_tcpclient_send(pclient,content_type,strlen(content_type));//content-beforetuobao_tcpclient_send(pclient,content_before,strlen(content_before));//contenttuobao_tcpclient_send(pclient,content,len);    //content-endtuobao_tcpclient_send(pclient,content_end,strlen(content_end));/*it's time to recv from server*/if(tuobao_tcpclient_recv(pclient,&lpbuf,0) <= 0){if(lpbuf) free(lpbuf);return -2;}printf("接收响应:\n%s\n",lpbuf);    /*响应代码,|HTTP/1.0 200 OK|     *从第10个字符开始,第3位     * */    memset(post,0,sizeof(post));    strncpy(post,lpbuf+9,3);    if(atoi(post)!=200){        if(lpbuf) free(lpbuf);        return atoi(post);    }    ptmp = (char*)strstr(lpbuf,"\r\n\r\n");    if(ptmp == NULL){        free(lpbuf);        return -3;    }    ptmp += 4;/*跳过\r\n*/    len = strlen(ptmp)+1;    *response=(char*)malloc(len);    if(*response == NULL){        if(lpbuf) free(lpbuf);        return -1;    }    memset(*response,0,len);    memcpy(*response,ptmp,len-1);    /*从头域找到内容长度,如果没有找到则不处理*/    ptmp = (char*)strstr(lpbuf,"Content-Length:");    if(ptmp != NULL){        char *ptmp2;        ptmp += 15;        ptmp2 = (char*)strstr(ptmp,"\r\n");        if(ptmp2 != NULL){            memset(post,0,sizeof(post));            strncpy(post,ptmp,ptmp2-ptmp);            if(atoi(post)<len)                (*response)[atoi(post)] = '\0';        }    }    if(lpbuf) free(lpbuf);    return 0;}int http_post(tuobao_tcpclient *pclient,char *page,char *request,char **response){    char post[300],host[100],content_len[100];    char *lpbuf,*ptmp;    int len=0;    lpbuf = NULL;    const char *header2="User-Agent: Tuobao Http 0.1\r\nCache-Control: no-cache\r\nContent-Type: application/x-www-form-urlencoded\r\nAccept: */*\r\n";    sprintf(post,"POST %s HTTP/1.0\r\n",page);    sprintf(host,"HOST: %s:%d\r\n",pclient->remote_ip,pclient->remote_port);    sprintf(content_len,"Content-Length: %d\r\n\r\n",strlen(request));    len = strlen(post)+strlen(host)+strlen(header2)+strlen(content_len)+strlen(request)+1;    lpbuf = (char*)malloc(len);    if(lpbuf==NULL){        return -1;    }    strcpy(lpbuf,post);    strcat(lpbuf,host);    strcat(lpbuf,header2);    strcat(lpbuf,content_len);    strcat(lpbuf,request);    if(!pclient->connected){        tuobao_tcpclient_conn(pclient);    }    if(tuobao_tcpclient_send(pclient,lpbuf,len)<0){        return -1;    }printf("发送请求:\n%s\n",lpbuf);    /*释放内存*/    if(lpbuf != NULL) free(lpbuf);    lpbuf = NULL;    /*it's time to recv from server*/    if(tuobao_tcpclient_recv(pclient,&lpbuf,0) <= 0){        if(lpbuf) free(lpbuf);        return -2;    }printf("接收响应:\n%s\n",lpbuf);    /*响应代码,|HTTP/1.0 200 OK|     *从第10个字符开始,第3位     * */    memset(post,0,sizeof(post));    strncpy(post,lpbuf+9,3);    if(atoi(post)!=200){        if(lpbuf) free(lpbuf);        return atoi(post);    }    ptmp = (char*)strstr(lpbuf,"\r\n\r\n");    if(ptmp == NULL){        free(lpbuf);        return -3;    }    ptmp += 4;/*跳过\r\n*/    len = strlen(ptmp)+1;    *response=(char*)malloc(len);    if(*response == NULL){        if(lpbuf) free(lpbuf);        return -1;    }    memset(*response,0,len);    memcpy(*response,ptmp,len-1);    /*从头域找到内容长度,如果没有找到则不处理*/    ptmp = (char*)strstr(lpbuf,"Content-Length:");    if(ptmp != NULL){        char *ptmp2;        ptmp += 15;        ptmp2 = (char*)strstr(ptmp,"\r\n");        if(ptmp2 != NULL){            memset(post,0,sizeof(post));            strncpy(post,ptmp,ptmp2-ptmp);            if(atoi(post)<len)                (*response)[atoi(post)] = '\0';        }    }    if(lpbuf) free(lpbuf);    return 0;}int main(){    tuobao_tcpclient client;    char *response = NULL;    printf("开始组包\n");    tuobao_tcpclient_create(&client,"127.0.0.1",80);//    if(http_post(&client,"/recv_file.php","f1=hello",&response)){//        printf("失败!\n");//        exit(2);//    }    http_post_file(&client,"/recv_file.php","/home/gumh/time_1970_186.jpg",&response);    printf("响应:\n%d:%s\n",strlen(response),response);    free(response);    return 0;}






1 0
原创粉丝点击