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
- linux c 实现 http post的代码-1
- linux http post的实现 -2
- linux c socket 实现http get/post请求
- linux C 实现HTTP get 及post 请求
- C 语言Socket 实现http 带参数的POST请求
- C++/C 实现http GET/POST操作
- Linux实用技巧-CURL实现HTTP的GET POST方法
- HTTP POST上传文件代码实现
- Linux C语言Http POST上传图片
- Linux下用c语言实现发送http请求 方式可以Get或者Post
- Linux下用c语言实现发送http请求 方式可以Get或者Post
- aiyao Linux下用c语言实现发送http请求 方式可以Get或者Post
- http post 请求的示例代码
- C语言典型代码---Curl实现POST
- andorid:HTTP Post 代码
- 一段c语言实现的发送http消息代码
- Linux下模拟ping命令的C代码实现1
- 实现HTTP-POST的Edit Action方法
- 将String保存成文件
- 安卓注解那些事儿
- 黑板客爬虫闯关第二关
- NSArray 排序用法
- 高并发Web服务的演变:节约系统内存和CPU
- linux c 实现 http post的代码-1
- 猜数字小游戏
- 第三周-项目二
- js ajax 加载图片 img的简单方法
- [LeetCode]Count Primes
- 加密问题(良心干货)
- git submodule子模块
- web测试工具
- Android Studio下添加引用jar文件和so文件