Windows版単純な client program †前節の単純な clinet program の Windows 版を書いてみる。Windows の場合、socket library は WINSOCK2 と呼ばれている通常の DLL(Dynamic Link library) として提供されている。Library interface は ws2_32.lib である。 開始時に WSAStartup 関数を呼び出して、library を(dynamic に)load し、終了時に WSACleanup 関数を呼び出して解放する必要がある点を除けば、ほぼ同じである。 違いは、
といったところである。 なお、getaddrinfo 関数を使うには、_WIN32_WINNT が 0x0501 以上である必要がある。従って 自動的に設定されない場合は compile 時に _WIN32_WINNT を設定する必要がある。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #include <ws2tcpip.h> #define MY_BUFSIZE 1024 static char buf[MY_BUFSIZE]; int main(int argc, char* argv[]) { struct sockaddr_in saddr; struct sockaddr_in* resaddr; struct addrinfo hints; struct addrinfo* res; SOCKET sd; int err; int port; const char* host; size_t nrecv; size_t n; WORD wReqVersion; WSADATA wsa; /* Start the WinSock library */ wReqVersion = MAKEWORD(2,2); if((err = WSAStartup(wReqVersion, &wsa)) != 0) return err; if((LOBYTE(wsa.wVersion) != 2) || (HIBYTE(wsa.wVersion) != 2)) { WSACleanup(); return (-1); } /* Check the command line */ if((argc != 2) && (argc != 3)) { fprintf(stderr, "Usage: %s host [port]\n", argv[0]); WSACleanup(); return (-1); } /* Set the hostname and port number */ res = 0; port = 80; host = argv[1]; if(argc == 3) { port = atoi(argv[2]); if(port <= 0) { fprintf(stderr, "Illegal port number (%d)\n", port); WSACleanup(); return (-1); } } /* Setup the address */ memset(&saddr, 0, sizeof(saddr)); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = 0; hints.ai_protocol = 0; if((err = getaddrinfo(host, 0, &hints, &res)) != 0) { WSACleanup(); return err; } resaddr = (struct sockaddr_in*)res->ai_addr; saddr.sin_family = AF_INET; saddr.sin_port = htons((u_short)port); saddr.sin_addr = resaddr->sin_addr; freeaddrinfo(res); /* Create socket */ if((sd = socket( PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { err = WSAGetLastError(); WSACleanup(); return err; } /* Connect to the host */ if(connect(sd, (const struct sockaddr*)&saddr, sizeof(saddr)) == SOCKET_ERROR) { err = WSAGetLastError(); WSACleanup(); return err; } /* Send the http request */ send(sd, "GET / HTTP/1.0\r\n\r\n", 18, 0); /* Receive until connection closed */ while((nrecv = recv(sd, buf, MY_BUFSIZE, 0)) > 0) { for(n = 0; n < nrecv; n++) fputc((int)buf[n], stdout); } /* Close our socket */ closesocket(sd); WSACleanup(); return 0; } 上の source を n03.c という名前のファイルに保存したとすると、compile/link は MinGW の場合は、 C:\>gcc -Wall -D_WIN32_WINNT=0x0501 n03.c -lws2_32 とする。 Microsoft Visual C++ の場合は、 C:\>cl /W3 /EHsc /D_WIN32_WINNT=0x0501 n03.c ws2_32.lib とする。 |