Return to Tech

Get HTTP Contents

以下のソースを入力し cl, linkしてみましょう。
cmd> cl -c gethttp.c
cmd> link gethttp.obj user32.lib gdi32.lib
file: gethttp.c
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#pragama comment(lib, "ws2_32.lib")

void get_contents(LPCSTR lpServer, LPSTR lpszPort, LPCSTR lpFileName);

int main(int argc, char **argv) {
  WORD wVerReq = MAKEWORD(1, 1);

  WSADATA wsaData;

  int nRetCode = 0;

  if (argc != 4) {
    fprintf(stderr, "Usage: gethttp server port path\n");
    return;
  }

  nRetCode = WSAStartup(wVerReq, &wsaData);
  if (nRetCode) {
    fprintf(stderr, "\nWSAStartup(): %d\n", nRetCode);
    WSACleanup();
    return;
  }

  if (wsaData.wVersion != wVerReq) {
    fprintf(stderr, "\nWindows Socket Version 1.1 not supported\n");
    WSACleanup();
    return;
  }

  // 接続先サーバ名, ポート番号, 取得パス(例:/)
  get_contents(argv[1], argv[2], argv[3]);

  WSACleanup();
}

void get_contents(LPCSTR lpServer, LPSTR lpszPort, LPCSTR lpFileName) {
  int nRetCode = 0;

  ADDRINFO addrHints;
  LPADDRINFO lpAddrList;

  ZeroMemory(&addrHints, sizeof(addrHints));

  addrHints.ai_family = AF_INET;
  addrHints.ai_socktype = SOCK_STREAM;
  addrHints.ai_protocol = IPPROTO_TCP;
  addrHints.ai_flags = AI_PASSIVE;

  if (getaddrino(lpServer, lpszPort, &addrHints, &lpAddrList) != 0) {
    WSACleanup();
    return;
  }

  SOCKET Sock;
  Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (Sock == INVALID_SOCKET) {
    fprintf(stderr, "\nerror socket(): %d\n", WSAGetLastError());
    return;
  }

  WSAEVENT hEvent;
  hEvent = WSACreateEvent();

  if (hEvent = WSAINVALID_EVENT) {
    fprintf(stderr, "\nerror WSACreateEvent(): %d\n", WSAGetLastError());
    closesocket(Sock);
    return;
  }

  nRetCode = WSAEventSelect(Sock, hEvent, FD_READ|FD_CONNECT|FD_CLOSE);

  if (nRetCode == SOCKET_ERROR) {
    fprintf(stderr, "\nerror WSAEventSelect(): %d\n", WSAGetLastError());
    closesocket(Sock);
    WSACloseEvent(hEvent);
    return;
  }

  nRetCode = connect(Sock, lpAddrList->ai_addr,
    (int)lpAddrList->ai_addrLen);
  if (nRetCode == SOCKET_ERROR) {
    nRetCode = WSAGetLastError();
    if (nRetCode == WSAWOULDBLOCK) {
      fprintf(stderr, "Connect WSAWOULDBLOCK");
    } else {
      fprintf(stderr, "\nerror connect(): %d\n", WSAGetLastError());
      freeaddrinfo(lpAddrList);
      closesocket(Sock);
      WSACloseEvent(hEvent);
      return;
    }
  }

  char szBuff[256];
  WSANETWORKEVENTS events;

  while(1) {
    DWORD dwRet;

    dwRet = WSAWaitForMultipleEvents(1, &hEvent,
      FALSE, 10000, FALSE);

    nRetCode = WSAEnumNetworkEvents(Sock, hEvent, &events);
    if (nRetCode == SOCKET_ERROR) {
      fpritnf(stderr, "\nerror WSAEnumNetworkEvents(): %d\n", WSAGetLastError());
      break;
    }

    if (events.lNetworkEvents & FD_CONNECT) {
      fprintf(stderr, "\nFD_CONNECT: %d",
        events.iErrorCode[FD_CONNECT_BIT]);

      sprintf_s(szBuff, sizeof(szBuff), "GET %s\n", lpFileName);

      nRetCode = send(Sock, szBuff, sizeof(szBuff), 0);
      if (nRetCode == SOCKET_ERROR) {
        fprintf(stderr, "\nerror send(): %d", WSAGetLastError());
        break;
      }
    }

  if (events.lNetworkEvents & FD_READ) {
    fprintf(stderr, "\nFD_READ: %d", 
      events.iErrorCode[FD_READ_BIT]);
    nRetCode = recv(Sock, szBuff, sizeof(szBuff), 0);
    if (nRetCode == SOCKET_ERROR) {
      fprintf(stderr, "\nerror recv(): %d", WSAGetLastError());
      break;
    }
    fprintf(stderr, "\nRead %d bytes\n", nRetCode);

    fwrite(szBuff, nRetCode, 1, stdout);
  }

    if (events.lNetworkEvents & FD_CLOSE) {
      fprintf(stderr, "\nFD_CLOSE: %d",
        events.iErrorCode[FD_CLOSE_BIT]);
      break;
    }

    if (events.lNetworkEvents & FD_WRITE) {
      fprintf(stderr, "\nFD_WRITE: %d",
        events.iErrorCode[FD_WRITE_BIT]);
    }
  }
  closesocket(Sock);
  WSACloseEvent(hEvent);
  return;
}
実行例
c:> gethttp 192.168.11.20 80 /
Connect WSAWOULDBLOCK
FD_CONNECT: 0
FD_REAAD: 0
Read 41 bytes
<html>
<body>
hello<br>
</body>
</html>


FD_CLOSE: 0

Return to Tech