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