Linux 上写C++ (6)——SOCKET-TCP/IP 模拟HTTP接口

        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;

}

你可能感兴趣的:(Linux 上写C++ (6)——SOCKET-TCP/IP 模拟HTTP接口)