程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 練習使用 socket 發送簡單的 HTTP GET 請求

練習使用 socket 發送簡單的 HTTP GET 請求

編輯:C++入門知識

最近項目中有這樣的需求,需要在游戲中內嵌手機驗證模塊,而手機綁定信息保存在運營後台,游戲服務器無法直接訪問,所以就需要游戲服務器向運營後台發送一些 HTTP 請求來獲取這類的信息。 因為這部分功能寫在服務端,為了盡量避免服務器阻塞,在 recv 前加了 select 操作,並且為每個 HTTP 請求分配了一個線程。這裡是針對此需求做的一些練習。 [cpp]  #include <stdio.h>   #include <WinSock2.h>      #pragma comment(lib, "ws2_32.lib")      // 連接服務器發送消息並將接收數據保存到 pReceiveBuf 中,此過程會 select 並 recv 消息,直到沒有數據到達或者接收緩存已滿   int connectAndSendData(const char *szHost, unsigned short nPort, const char *pDataToSend, unsigned int nDataSize, char *pReceiveBuf = NULL, unsigned int *pnReceiveSize = NULL)   {       WORD wVersionRequested = MAKEWORD(1, 1);       WSADATA wsaData;          int err = ::WSAStartup(wVersionRequested, &wsaData);       if ( 0 != err )       {           printf("[connectAndSendData]: WSAStartup failed. return %d. \r\n", err);           return -1;       }          if ( wsaData.wVersion != wVersionRequested )       {           printf("[connectAndSendData]: wsaData.wVersion %d is not equal to wVersionRequested %d.\r\n", wsaData.wVersion, wVersionRequested);           ::WSACleanup();           return -2;       }          SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);       if ( INVALID_SOCKET == sock )       {           printf("[connectAndSendData]: socket error %d. \r\n", WSAGetLastError());           return -3;       }          struct hostent *p_hostent = gethostbyname(szHost);       if( NULL == p_hostent )       {           printf("[gethostbyname]: socket error %d. \r\n", WSAGetLastError());           ::closesocket(sock);           ::WSACleanup();           return -4;       }          SOCKADDR_IN addr_server;       addr_server.sin_family  = AF_INET;       addr_server.sin_addr    = *((struct in_addr*)p_hostent->h_addr);       memset(addr_server.sin_zero, 0, 8);       addr_server.sin_port    = htons(nPort);          err = ::connect(sock, (SOCKADDR*)&addr_server, sizeof(addr_server));       if ( SOCKET_ERROR == err )       {           printf("[connectAndSendData]: connect %s:%d error %d. \r\n", szHost, nPort, WSAGetLastError());           ::closesocket(sock);           ::WSACleanup();           return -5;       }          err = ::send(sock, pDataToSend, nDataSize, 0);       if ( SOCKET_ERROR == err )       {           printf("[connectAndSendData]: send error %d. \r\n", WSAGetLastError());       }          if ( NULL != pReceiveBuf && NULL != pnReceiveSize )       {           char *p_receive = pReceiveBuf;           char *p_buf = p_receive;           int n_buf_len = *pnReceiveSize;           int n_len = n_buf_len - 1;           int n_read = 0;           char temp[256];           int n_head_len = -1;           int n_content_len = -1;           const char *content = NULL;              while (1)           {               fd_set fds;               FD_ZERO(&fds);               FD_SET(sock, &fds);               struct timeval timeo;               timeo.tv_sec = 10;               timeo.tv_usec = 1000;                  int ret = select(sock, &fds, NULL, NULL, &timeo);               if (ret <= 0)                   break;                  if (FD_ISSET(sock, &fds))               {                   n_read = ::recv(sock, p_buf, n_len, 0);                   if (n_read <= 0)                       break;                      p_buf += n_read;                   n_len -= n_read;                   if ( n_len == 0 )                       break;                      const char *rnrn = strstr(p_receive, "\r\n\r\n");                   if (NULL != rnrn && rnrn < p_buf)                   {                       rnrn += 4;                       content = rnrn;                          if (-1 == n_content_len)                       {                           const char *content_length = strstr(p_receive, "Content-Length: ");                           if (NULL != content_length && content_length < p_buf)                           {                               content_length += 16;                               const char *rn = strstr(content_length, "\r\n");                               if (NULL != rn && rn < p_buf)                               {                                   int count = rn - content_length;                                   strncpy(temp, content_length, count);                                   temp[count] = '\0';                                   n_content_len = atoi(temp);                               }                           }                              if (-1 == n_content_len)                           {                               const char *rn = strstr(rnrn, "\r\n");                               if (NULL != rn && rn < p_buf)                               {                                   int count = rn - rnrn;                                   strncpy(temp, rnrn, count);                                   temp[count] = '\0';                                   if (1 == sscanf(temp, "%x", &n_content_len) )                                   {                                       n_content_len += 7; // 0D 0A 30 0D 0A 0D 0A                                       content = rn + 2;                                   }                               }                           }                              if (-1 == n_content_len)                           {                               const char *connection = strstr(p_receive, "Connection: ");                               if (NULL != connection && connection < p_buf)                               {                                   connection += 12;                                   const char *rn = strstr(connection, "\r\n");                                   if (NULL != rn && rn < p_buf)                                   {                                       int count = rn - connection;                                       strncpy(temp, connection, count);                                       temp[count] = '\0';                                       connection = _strupr(temp);                                       if (0 == strcmp(connection, "CLOSE"))                                           n_content_len = 0;                                   }                               }                           }                       }                   }                      if (NULL != content && n_content_len > 0)                   {                       n_head_len = content - p_receive;                       int n_cur_len = p_buf - p_receive;                       if ( n_cur_len >= n_head_len + n_content_len )                           break;                   }               }           }              n_len = n_buf_len - 1 - n_len;           n_buf_len = n_len;           p_receive[n_len] = '\0';       }          err = ::closesocket(sock);       if ( SOCKET_ERROR == err )       {           printf("[connectAndSendData]: closesocket error %d. \r\n", WSAGetLastError());       }          ::WSACleanup();          return 0;   }      int main()   {       char request_buffer[1024];       request_buffer[0] = '\0';          // 寫 HTTP 頭信息       // HTPP 頭可以有多行,每行都以 \r\n 結尾,最後再以 \r\n 結束       strcat(request_buffer, "GET /index.php?id=1 HTTP/1.1\r\n");       strcat(request_buffer, "Host: 127.0.0.1:80\r\n");       strcat(request_buffer, "Connection: keep-alive\r\n");       strcat(request_buffer, "Accept: */*\r\n");       strcat(request_buffer, "\r\n");          char receive_buff[102400];       unsigned n_receive_len = 102400;       receive_buff[0] = '\0';       connectAndSendData("127.0.0.1", 80, request_buffer, strlen(request_buffer), receive_buff, &n_receive_len);       printf(receive_buff);          getchar();       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved