http协议封装的底层分装的TCP/IP 协议,所以直接用tcp/ip调用的http也是可行的,此方法是整个框架中的最核心的方法的,有了此接口其他的一切都是好说。
//调用动态库,所有的方法调用此函数
string IVR_COMMON::HttpRequest_JSON(char *ip,char *port,char *url,char *strbufsize,char *strtimeout,char *PARAM)
{
string strPARAM="";
string response = "";
char ParamSYS[2048];
char ParamData[2048];
int time_ss=0;
int bufsize=atoi(strbufsize);
long timeout=atoi(strtimeout);
int sockfd, ret, i, h;
int nSize;
struct sockaddr_in servaddr;
char C_Param[2048];
string split="|data=|";
char str1[10240];
// char str2[102400];
char buf[10240];
char GBK_buf[10240];
char str_len[20];
socklen_t len;
fd_set fdread;
struct timeval tv;
//-----------------------------------------------------------
string StrPARAM(PARAM);
string StrParamSYS= MySplit( StrPARAM, split,0);
WriteLog("StrParamSYS",StrParamSYS);
string StrParamData= MySplit( StrPARAM, split,1);
WriteLog("StrParamData",StrParamData);
strcpy(ParamSYS,StrParamSYS.c_str());
strcpy(ParamData,StrParamData.c_str());
//-----------------------------------------------------------
char stimeout[10]="";
sprintf(stimeout, "%d", timeout);
WriteLog("timeout 超时时长",stimeout);
if((sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0)
{
WriteLog("sockfd","获取套接字失败"); return "";
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(port));
if(inet_pton(AF_INET,ip,&servaddr.sin_addr) <= 0)
{
return "IP,Port","ip地址和端口转换失败!";
}
if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))< 0 && errno != EINPROGRESS )
{
return "IP,Port","ip地址和端口错误,建立链接失败!";
}
WriteLog("IP,Port建立链接OK",ip);
struct linger so_linger;
so_linger.l_onoff = 1;
so_linger.l_linger = 0;
setsockopt(sockfd, SOL_SOCKET,SO_LINGER,&so_linger,sizeof so_linger);
len = strlen(ParamData);
sprintf(str_len,"%d",len);
memset(str1,0,10240);
strcat(str1,"POST ");
strcat(str1,url);
strcat(str1,ParamSYS);
strcat(str1," HTTP/1.1\n");
strcat(str1,"Host: ");
strcat(str1,ip);
strcat(str1,":");
strcat(str1,port);
strcat(str1,"\nContent-Type: application/x-www-form-urlencoded\n");
//strcat(str1,"\nContent-Type: text/xml\n"); //外围接口对应的 Content-Type 对影响报文解析,即便参数报文正确也会报错
strcat(str1,"Content-Length: ");
strcat(str1,str_len);
strcat(str1,"\n\n");
strcat(str1,ParamData);
strcat(str1,"\r\n\r\n");
//cout< WriteLog("REQUEST_PARAM",str1); ret = send(sockfd,str1,strlen(str1),0); if(ret < 0) { WriteLog("Send message fail","http请求发送失败,原因肯能是传输的参数失败,可以将参数拼成http串,放到浏览器地址栏测试,如果失败,说明借口有问题,需要和CRM那边联调测试"); close(sockfd); return "Send message fail"; } WriteLog("Send message Success","http请求发送成功!"); //FD_ZERO(&fdread); //长时间调用此方法 就造成内存溢出,多次调试之后将此监听去掉后系统正常 //FD_SET(sockfd,&fdread); while(1) { time_ss++; if(time_ss>timeout) { WriteLog("time out",strtimeout); close(sockfd); return "time out"; } tv.tv_sec = 0; //超时时长 tv.tv_usec = 100000; select(sockfd+1,NULL,NULL,NULL,&tv); WriteLog("time_ss",time_ss); memset(buf,0,10240); memset(GBK_buf,0,10240); i=recv(sockfd,buf,10240,0); if(i>0) { utf82gbk(GBK_buf, buf); response=response+GBK_buf; //socket 发送字串是按字节发送,如果 内容过长,会分开发送,接口分开取数据 如果找到以下字串表示数据已经接收完成一般情况下,直接一次就完成了 string EndFlag=response.substr(response.size()-8,4); string EndFlag1=EndFlag.substr(0,1); string EndFlag2=EndFlag.substr(3,1); // WriteLog("EndFlag",EndFlag); // WriteLog("EndFlag1",EndFlag1); // WriteLog("EndFlag2",EndFlag2); EndFlag=EndFlag.substr(0,1); if(EndFlag1=="}"&&EndFlag2=="0") { // WriteLog("response",response); WriteLog("select success","OK"); break; } else { continue; } } if(i <0) { close(sockfd); WriteLog("read","读取返回信息失败,有可能是参数 bufsize 的值过小造成"); break; } } close(sockfd); WriteLog("SUCCESS","OK"); return response; }