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<<str1<<"\n";
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;
}