Rover12421's Blog

The End.

Post提交数据

Post提交和Get提交的写法差不多。不过还是记录下。主要是感觉函数还是可以复用,以后可以直接把相关的处理函数拿来用。

在构造Post提交数据函数参照了API常用的一种手法,就是在传递位置长度的字符串变量的时候,可以先传0,让函数放回实际所需要的长度。这样写,既可以避免溢出,又不会浪费空间。不过API的实现我并不知道,只是借鉴了这种思路。

 

postfn.h

   1: #pragma once
   2: #include <WinSock.h>
   3: #pragma comment (lib, "ws2_32.lib")
   4: int fn_StructurePostData( const char *szAPostHeaderHost, const char *szAPostHeaderPage, const char *szASendPostData, char *szAPostData, int &nPostDataSize );
   5: int fn_InitWinSock( const char *szAHost, const int nPort, SOCKET &fsockt, SOCKADDR_IN &fsin );
   6: void fn_CleanupSocket( SOCKET fsock );

postfn.cpp

   1: #include "stdafx.h"
   2: #include "postfn.h"
   3: //构造POST结构
   4: //nPostDataSize:构造后的Post数据结构大小(IN_OUT)
   5: //szAPostData:返回的可以提交的Post数据(OUT)
   6: //如果nPostDataSize为0,则返回实际所需要的nPostDataSize大小,且不返回(处理)szAPostData,返回值为0
   7: //如果nPostDataSize不为0,则返回可以POST提交的szAPostData数据,返回值为szAPostData的大小
   8: int fn_StructurePostData( const char *szAPostHeaderHost, const char *szAPostHeaderPage, const char *szASendPostData, char *szAPostData, int &nPostDataSize )
   9:  {
  10:      int nMaxLen = nPostDataSize;
  11:      if (nPostDataSize == 0)
  12:      {
  13:          nMaxLen = MAX_POSTDATA_LEN;
  14:      }
  15:  
  16:      char *szAStructurePostData = new char[nMaxLen];
  17:      ZeroMemory(szAStructurePostData, nMaxLen);
  18:      char buff[128];
  19:      ZeroMemory(buff, sizeof(buff));
  20:  
  21:      //构造Post头
  22:      wsprintfA(buff, "POST /%s HTTP/1.0\r\n", szAPostHeaderPage);
  23:      strcat_s(szAStructurePostData, nMaxLen, buff);
  24:      strcat_s(szAStructurePostData, nMaxLen, "Accept:*/*\r\n");
  25:      strcat_s(szAStructurePostData, nMaxLen, "Accept-Language: zh-cn\r\n");
  26:      strcat_s(szAStructurePostData, nMaxLen, "Accept-Encoding: gzip, deflate\r\n");
  27:      strcat_s(szAStructurePostData, nMaxLen, "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n");
  28:  
  29:      ZeroMemory(buff, sizeof(buff));
  30:      wsprintfA(buff, "Content-Length: %ld\r\n", strlen(szASendPostData));
  31:      strcat_s(szAStructurePostData, nMaxLen, buff);
  32:  
  33:      ZeroMemory(buff, sizeof(buff));
  34:      wsprintfA(buff, "Host: %s\r\n", szAPostHeaderHost);
  35:      int err = _strupr_s(buff, sizeof(buff));
  36:      strcat_s(szAStructurePostData, nMaxLen, buff);
  37:  
  38:      strcat_s(szAStructurePostData, nMaxLen, "Content-Type: application/x-www-form-urlencoded\r\n");
  39:  
  40:      //POST头后面空一行添加需要发送的数据
  41:      strcat_s(szAStructurePostData, nMaxLen, "\r\n");
  42:  
  43:      if ( nPostDataSize == 0)
  44:      {
  45:          nPostDataSize = strlen(szAStructurePostData) + strlen(szASendPostData) + 1;
  46:          delete[] szAStructurePostData;
  47:          szAStructurePostData = NULL;
  48:          return 0;
  49:      }
  50:      else
  51:      {
  52:          strcat_s(szAStructurePostData, nMaxLen, szASendPostData);
  53:          sprintf_s(szAPostData, nMaxLen, szAStructurePostData);
  54:          delete[] szAStructurePostData;
  55:          szAStructurePostData = NULL;
  56:          return strlen(szAPostData);
  57:      }
  58:  
  59:  }
  60:  
  61: //初始化WinSock
  62: //返回值:
  63: //0:初始化成功
  64: //1:WSAStartup失败
  65: //2:socket失败
  66: //3.gethostbyname失败
  67: int fn_InitWinSock( const char *szAHost, const int nPort, SOCKET &fsockt, SOCKADDR_IN &fsin )
  68: {
  69:     WSAData fWsaData;
  70:     int err = WSAStartup(MAKEWORD(2, 2), &fWsaData);
  71:     if (err != 0)
  72:     {
  73:         fsockt = INVALID_SOCKET;
  74:         return 1;
  75:     }
  76:  
  77:     fsockt = socket(AF_INET, SOCK_STREAM, 0);
  78:     if (fsockt == INVALID_SOCKET)
  79:     {
  80:         WSACleanup();
  81:         return 2;
  82:     }
  83:  
  84:     struct hostent *pHost;
  85:     pHost = gethostbyname(szAHost);
  86:     if (pHost == NULL)
  87:     {
  88:         //closesocket(fsockt);
  89:         WSACleanup();
  90:         return 3;
  91:     }
  92:  
  93:     //char *pHostIP = *pHost->h_addr_list;
  94:     //fsin.sin_addr.s_addr = *((DWORD*)pHostIP);
  95:     char *pHostIP = inet_ntoa(*(struct in_addr *)*pHost->h_addr_list);
  96:     fsin.sin_addr.s_addr = inet_addr(pHostIP);
  97:  
  98:     fsin.sin_family = AF_INET;
  99:     fsin.sin_port = htons((unsigned short)nPort);
 100:     
 101:     return 0;
 102: }
 103:  
 104: //释放清理socket
 105: void fn_CleanupSocket( SOCKET fsock )
 106: {
 107:     closesocket(fsock);
 108:     WSACleanup();
 109: }

Testpost.cpp

   1: #include "stdafx.h"
   2: #include "postfn.h"
   3: #define MAX_POSTDATA_LEN 2048
   4:  
   5: int _tmain(int argc, _TCHAR* argv[])
   6: {
   7:     char szAPostHost[] = "www.rover12421.com";
   8:     char szAPostPage[] = "post.php";
   9:     char szASendData[] = "This is Post Send data!";
  10:     char *szAPostData = NULL;
  11:     int nPostDataSize = 0;
  12:     fn_StructurePostData(szAPostHost, szAPostPage, szASendData, szAPostData, nPostDataSize);
  13:     szAPostData = new char[nPostDataSize];
  14:     ZeroMemory(szAPostData, nPostDataSize);
  15:     fn_StructurePostData(szAPostHost, szAPostPage, szASendData, szAPostData, nPostDataSize);
  16:     printf("\n*****************\nnPostDataSize=%d\n%s\n**********************\n", nPostDataSize, szAPostData);
  17:  
  18:     SOCKET fsock = INVALID_SOCKET;
  19:     int nport = 80;
  20:     SOCKADDR_IN fsin = {0};
  21:     int err = fn_InitWinSock(szAPostHost, nport, fsock, fsin);
  22:     if (err != 0)
  23:     {
  24:         printf("fn_InitWinSock  faild");
  25:         return 1;
  26:     }
  27:  
  28:     if (connect(fsock, (SOCKADDR*)&fsin, sizeof(SOCKADDR)))
  29:     {
  30:         printf("\nconnect faild %ld\n", fsock);
  31:         fn_CleanupSocket(fsock);
  32:         return 1;
  33:     }
  34:  
  35:     char szARecvPostData[MAX_POSTDATA_LEN];
  36:     ZeroMemory(szARecvPostData, sizeof(szARecvPostData));
  37:  
  38:     send(fsock, szAPostData, strlen(szAPostData), 0);
  39:     int nRecvSize = recv(fsock, szARecvPostData, MAX_POSTDATA_LEN - 1, 0);
  40:     printf("\nPost return(%d):\n-----------------------------\n%s\n-----------------------------\n", nRecvSize, szARecvPostData);
  41:  
  42:     //如果接收的长度是不确定长度,可以使用while循环接收全部数据
  43:     //while (nRecvSize != 0)
  44:     //{
  45:     //    ZeroMemory(szARecvPostData, sizeof(szARecvPostData));
  46:     //    nRecvSize = recv(fsock, szARecvPostData, 1023, 0);
  47:     //    printf("\nPost return(%d):\n-----------------------------\n%s\n-----------------------------\n", nRecvSize, szARecvPostData);
  48:     //}
  49:     
  50:     delete []szAPostData;
  51:     szAPostData = NULL;
  52:  
  53:     return 0;
  54: }

Comments