linux c 实现 http post的代码-1
需要在开发板上实现以http的协议上传图片的功能。参考了以下作者的文章:http://www.cnblogs.com/linbc/archive/2009/03/21/1400108.htmlhttp://blog.csdn.net/sjin_1314/article/details/41776679http://www.xuebuyuan.com/989667.htm
·
需要在开发板上实现以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 1024
int 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 not
struct 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 character
printf("%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");
//send
if(!pclient->connected){
tuobao_tcpclient_conn(pclient);
}
//content-type
tuobao_tcpclient_send(pclient,content_type,strlen(content_type));
//content-before
tuobao_tcpclient_send(pclient,content_before,strlen(content_before));
//content
tuobao_tcpclient_send(pclient,content,len);
//content-end
tuobao_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)