您的位置:首页 > 理论基础 > 计算机网络

[转] linux下纯C简单的HTTP POST请求 客户端模型

2009-05-13 14:15 337 查看

交代一下故事背景,国内某保险公司,最近上ILOG规则引擎项目,题外话, 对于保险里面的车险核保,真的是相当合适.据说,目前规则引擎最成功的就是ILOG了,我稍微看了一下他们的规则描述语言,感觉好傻啊,用中文描述,我觉得这东西要是可以用导图的那种方式,很发散的方式去处理一定很完美! 回到正题上,因为公司的核心业务系统是使用pro*c编写的服务运行于IBM AIX上面,并且通过中间件与前端通讯,怎么与java的ILOG规则引擎通讯呢?刚开始想着通过gSoap来实现c对web service的调用,但最后因为安装这个包肯定得通过系统管理员,相当麻烦,而且从来没有用过,不知道是否好用,所以ILOG那边增加一个DTO转换层,即将我们发送过去的xml转换成web services调用,并将返回结果也转换成XML;简单的说就是核心后台通过HTTP POST打包xml发送请求,并且规则引擎那边也返回xml来实现! 晕,走题有点严重! 其实无非要实现有两点, TCP客户端的模型 HTTP POST协议
先来看看我的TCP模型的实现
#ifndef _TUOBAO_TCP_CLIENT_
#define _TUOBAO_TCP_CLIENT_

#include <netinet/in.h>
#include <sys/socket.h>

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
上面的代码应该也不用说太多,光看这个这些函数的命名也差不多知道嘛意思了 定义一个结构体,有远程IP及端口,连接状态(注:连接状态是为了保持长连接用的,但事实上post请求的时候,根本就没有保持,所以,基本上没用) 然后是五个tcp函数 tuobao_tcpclient_create:根据服务器IP或者域名,以及端口填充tcpclient结构,主要是申请个socket及填一下sockaddr_in tuobao_tcpclient_conn:连接到远程端口,并修改tcpclient的连接状态 tuobao_tcpclient_recv:接收远程指定字节数的数据,并分配空间到lpBuf,如果size为0,就阻塞直到连接关闭 tuobao_tcpclient_send:发送buf,size为buf长度 tuobao_tcpclient_close:关闭socket并且设置连接状态 好了,直接贴代码算了 linbc@cheng-ubuntu:~/workspace/httpclient$ sudo nc -l -p 80
[sudo] password for linbc:
POST /a.b HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, */*
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30618)
Host: 192.168.1.103
Content-Length: 12
Connection: Keep-Alive
Cache-Control: no-cache

input1=hello
好了,基本上知道post请求的http头 下面直接看代码 #include "tuobao_tcpclient.h"
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);
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,"/i.php","f1=hello",&response)){
printf("失败!\n");
exit(2);
}
printf("响应:\n%d:%s\n",strlen(response),response);
free(response);
return 0;
} 写个简单的makefile objects = tuobao_tcpclient.o httppost.o
httppost: $(objects)
cc -o httppost $(objects)
tuobao_tcpclient.o: tuobao_tcpclient.h
httppost.o:
.PHONY : clean
clean :
@echo 正在移除 -rm httppost $(objects)
好了,万事OK了。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: