因为实际需要,要用C/C++模拟HTML提交FORM数据,可是找了半天没找好的解决办法,求高手指教。(郁闷中)以下是要需要模拟的HTML文本
//---------------------------------------------------------------------
<html>
<head>
<title>Untitled Document</title>
</head><form method="post" action="the URL of POST" name="formdata">
  <p> 
    <textarea name="content" cols="80" rows="20"></textarea>
  </p>
  <p> 
    <input type="submit" name="Submit" value="Submit">
    <input type="reset" name="Reset" value="Reset">
  </p>
</form>
</html>//---------------------------------------------------------------------

解决方案 »

  1.   

    MFC的
    int COAMinderDlg::GetTaskAmount()
    {
    iAmount=0;
    iMsgAmount=0;
    iFileAmount=0;
    CInternetSession m_Session("DigitalTitan");
        CHttpConnection* pServer=NULL;
        CHttpFile* pFile=NULL;
    CHttpFile* pTaskFile=NULL;
        CString strServerName=strServerIP;
        INTERNET_PORT nPort=(INTERNET_PORT)atoi(strServerPort);
    CString strURL=strLoginAddress;
    try
    {
            pServer=m_Session.GetHttpConnection(strServerName,nPort);
    pFile=pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,strURL,NULL,1,NULL,NULL,INTERNET_FLAG_EXISTING_CONNECT);
            CString strHeaders=_T("Content-Type: application/x-www-form-urlencoded");
            CString strFormData;
    strFormData.Format("UserName=%s&Password=%s&action=submit",strLoginUserName,strLoginPassword);
    //AfxMessageBox(strFormData,MB_ICONINFORMATION);
    if(pFile->SendRequest(strHeaders,(LPVOID)(LPCTSTR)strFormData,strFormData.GetLength())==0)
    {
    //AfxMessageBox("网络异常...",MB_ICONINFORMATION);
    pFile->Close();
    delete pFile;
    pServer->Close();
    delete pServer;
    m_Session.Close();
    }
    else
    {
    pFile->ReadString(strInfo);
    if(strInfo.Find("Apache Tomcat/4.1.18 - Error report",0)!=-1)
    {
    AfxMessageBox("服务器产生错误.",MB_ICONINFORMATION);
    return 0;
    }
    pFile->Close();
    delete pFile;
    pServer->Close();
    delete pServer;

    pTaskFile=(CHttpFile*)m_Session.OpenURL(strLoginDataAddress);
    CString strBuf;
    CString strText;
    while(pTaskFile->ReadString(strText)) 
    {
    strBuf+="\r\n";
    strBuf+=strText;
    }
    pTaskFile->Close();
    delete pTaskFile;
    m_Session.Close();
    //AfxMessageBox(strBuf,MB_ICONINFORMATION);
    int iBegin,iEnd;
    iBegin=0;iEnd=0;
    CString strTemp;
    strTemp="";
    //信息提取
    //关键字一
    iBegin=strBuf.Find("更多方案",0);
    if(iBegin!=-1)
    {
    //关键字二
    iEnd=strBuf.Find("已办理方案</font>",iBegin);
    strTemp=strBuf.Mid(iBegin+9,iEnd-(iBegin+9));
    strTemp.MakeLower();
    //分隔符
    int iResult=strTemp.Find("<tr",0);
    if(iResult==-1)
    {
    //
    }
    else if(iResult<strTemp.GetLength())
    {
    while(iResult!=-1)
    {
    iAmount++;
    iResult=strTemp.Find("<tr",iResult+3);
    }
    //修正结果
    iAmount=iAmount-5;
    }
    }
    //另关键字:新申请(3)新归档方案(0)
    iBegin=strBuf.Find("新申请(",0);
    iEnd=strBuf.Find(")",iBegin);
    strTemp=strBuf.Mid(iBegin+9,iEnd-(iBegin+9));
    iMsgAmount=atoi(strTemp); iBegin=strBuf.Find("新归档方案(",0);
    iEnd=strBuf.Find(")",iBegin);
    strTemp=strBuf.Mid(iBegin+13,iEnd-(iBegin+13));
    iFileAmount=atoi(strTemp);
    }
    }
        catch(CInternetException* e)
    {
    char strErrorBuf[255];
    e->GetErrorMessage(strErrorBuf,255,NULL);
    AfxMessageBox(strErrorBuf,MB_ICONINFORMATION);
    pFile=NULL;
    delete pFile;
    pTaskFile=NULL;
    delete pTaskFile;
    pServer=NULL;
    delete pServer;
    m_Session.Close();
    return 0;
    }
    return iAmount;
    }
      

  2.   

    刀锋的:char request[]="GET /Develop/Read_Article.asp?Id=4816 HTTP/1.1\r\n";char header[]=
    "Accept: */*\r\n"
    "Accept-Language: zh-cn\r\n"
    "Accept-Encoding: gzip, deflate\r\n"
    "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)\r\n"
    "Host: www.csdn.net\r\n"
    "Connection: Keep-Alive\r\n"
    "Cookie: ASPSESSIONIDCCABSCAD=JACFBJLDAKFIELKFCHFDNPHN;\r\n"
    "ABCDEF=oiUCTNhlXF62fTpukWOwMLcxxLpFecMSPdKZ7YtPqkg372acN2Wz4A%25253d%25253d;\r\n"
    "QWERTOP=1399; userid=379347; daynum=0\r\n"
    "\r\n";res=send(sock, request,strlen(request),0);
    res=send(sock, header,strlen(header),0);
      

  3.   

    TO gjd111686(数字金刚): 呵呵!先谢了,但是你这个方法,我早就用过了,但是肯定是不行的,我用sniffer抓包看了,通过MFC的SendRequest(strHeaders,strData, nLen)方式发送的是原数据,而通过FORM提交的DATA,每个字符之间都有修饰符(%之类的),包的内容不一致,还是没有解决问题啊!:(继续等待中
      

  4.   

    你可能是提交的方式不同,POST和GET.你组织的数据可能是multipart/form-data都有关系,只有修饰符是编码问题,应该没有关系
      

  5.   

    只要具有象浏览器那样向HTTP服务器发送数据的功能,我们就可以模拟浏览器的登陆等操作,通过程序来发送信息。我们打算使用WinInet函数来实现与HTTP服务器的通信。   主要用到的模拟浏览器的函数。/*****************************************************************
    * 函数介绍: 执行HTTP的Post或Get方法
    * 输入参数: TCHAR* hdrs       - HTTP头
                TCHAR* accept     - Accept类型
                TCHAR* Method     - POST 或 GET
                TCHAR* frmdata    - 要提交的数据
                TCHAR* ServerName - 服务器地址
                TCHAR* FormAction - 数据提交到的网页名称
    * 输出参数: 无
    * 返 回 值: int               - 返回操作状态(见MSDN)
    *****************************************************************/
      

  6.   

    int doHTTP(TCHAR* hdrs, TCHAR* accept, TCHAR* Method, TCHAR* frmdata, TCHAR* ServerName, TCHAR* FormAction)
    {
       // 创建Internet
       HINTERNET hSession = InternetOpen("MyAgent", 
                                         INTERNET_OPEN_TYPE_PRECONFIG, 
                                         NULL, 
                                         NULL,
                                         0);
       if (!hSession)
       {
           return 5;
       }
       // 连接服务器
       HINTERNET hConnect = InternetConnect(hSession, 
                                            ServerName, 
                                            INTERNET_DEFAULT_HTTP_PORT, 
                                            NULL, 
                                            NULL, 
                                            INTERNET_SERVICE_HTTP, 
                                            0, 
                                            1);
       if (!hConnect)
       {
           return 2;
       }
       // 创建一个请求
       HINTERNET hRequest = HttpOpenRequest(hConnect,
                                            Method,
                                            FormAction,
                                            HTTP_VERSION,
                                            NULL, 
                                            (const char**)&accept,
                                            0, 
                                            1);
       if (!hRequest)
       {
           return 2;
       }
       // 发送请求
       BOOL bSendRequest = HttpSendRequest(hRequest,
                                           hdrs,
                                           strlen(hdrs),
                                           frmdata,
                                           strlen(frmdata));
       if (!bSendRequest)
       {
           return 2;
       }////////////////////////调试用/////////////////
    #ifdef _DEBUG
       int bDoLoop = 1;
       LPTSTR szReadBuffer;
       DWORD lNumberOfBytesRead;
       FILE* f1;
       szReadBuffer = (LPTSTR) malloc(500);
       ZeroMemory(szReadBuffer, 500);
       if ((f1=fopen("c:\\test.htm", "w"))!=NULL)
       {
           while(bDoLoop)
           {
               bDoLoop = InternetReadFile(hRequest, szReadBuffer, 500, &lNumberOfBytesRead);
               fseek(f1, 0L, SEEK_END);
               fwrite(szReadBuffer, sizeof(szReadBuffer), lNumberOfBytesRead, f1); 
               if (lNumberOfBytesRead<500)
                   bDoLoop = 0;
           }
       }
       fclose(f1);
       free(szReadBuffer);
    #endif
    //////////////////////////////////////////////////   // 清除句柄
       if (hRequest)
           InternetCloseHandle(hRequest);
       if (hConnect)
           InternetCloseHandle(hConnect);
       if (hSession)
           InternetCloseHandle(hSession);   return 0;
    }/*****************************************************************
    * 函数介绍: 发送短信函数
    * 输入参数: char* lpGateway  - 发送网关名称
                char* lpUserName - 发送者登陆账号
                char* lpPassword - 发送者登陆密码
                char* lpPhone    - 接收者手机号码
                char* lpContent  - 发送内容
                char* lpNickName - 发送者昵称
                char* lpExtent   - 扩展信息                                      
    * 输出参数: 无
    * 返 回 值: int       00     - 操作完成,结果未知
                          01     - 网关代号不存在
                          02     - 网络连接超时
                          03     - 用户中止操作
                          04     - 网关/账号/手机/短信内容空白或非法
                          05     - 出现其他错误
    *****************************************************************/
    SENDSMS_API int CALLAGREEMENT SendSMS(char* lpGateway,
                                            char* lpUserName, 
                                          char* lpPassword,
                                          char* lpPhone,   
                                          char* lpContent,
                                          char* lpNickName,
                                          char* lpExtent
                                          )
    {
        int Result;
        static TCHAR hdrs[] = _T("Content-Type: application/x-www-form-urlencoded");
        static TCHAR accept[] = _T("Accept: */*");
        static TCHAR frmdata[1024];    // 登陆姓名,密码等不允许为空
        if ((strlen(lpGateway)<=0)||(strlen(lpUserName)<=0)||
              (strlen(lpPassword)<=0)||(strlen(lpPhone)<=0)||(strlen(lpContent)<=0))
            return 4;    // 选择网易网关发送
        if (strcmp(lpGateway, "163.com")==0)
        {
            // 登录短信发送系统
            sprintf(frmdata, "username=%s&password=%s", lpUserName, lpPassword);
            Result = doHTTP(hdrs, accept, "POST", frmdata, "reg4.163.com", "/in.jsp");
            
            // 发送短信
            if (strlen(lpNickName)>0)
                sprintf(frmdata, "send=1&phone=%s&message=%s--%s", lpPhone, lpContent, lpNickName);
            else
                sprintf(frmdata, "send=1&phone=%s&message=%s", lpPhone, lpContent);
            Result = doHTTP(hdrs, accept, "POST", frmdata, "sms.163.com", "/service/sendmsg_pop.php");
            
            // 退出短信发送系统
            sprintf(frmdata, "username=%s", lpUserName);
            Result = doHTTP(hdrs, accept, "GET", frmdata, "reg4.163.com", "/Logout.jsp");        return Result;
        }
        // 选择搜狐网关发送
        if (strcmp(lpGateway, "sohu.com")==0)
        {
            Result = 1;
            return Result;
        }    // 网关代号不存在
        return 1;

    以上是一个利用网页发送短信息的函数,里面有你想要的功能。。
      

  7.   

    搞定了,THANKS ALL。事实上大家的方法都是对的,但是关键在于FORM提交的时候,遇到非数字或字符,FORM会进行字符转换,转换成十六进制的转义字符,所以我提交的时候总是出错。所以模拟提交FORM时,要对发送的数据进行一次字符转换,然后提交。