HTTP通信をするプログラムを書いてみました。WinScok2とBoost.Asioでそれぞれ書いてみました。簡単にするためにTCPで同期通信するプログラムです。WinSockの参考に「猫でもわかるWindowsプログラミング」を使ったのでアクセスするページがそうなっていますが、特にそれ以上の意味はありません。
WinSock
//WinSockでHTTP通信を行う #include <WinSock2.h> #include <iostream> #include <string> using namespace std; int main() { WSADATA wsadata;//ソケット情報を格納する構造体 //WinSockの初期化 if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) { cout << "winsock startup failed.\n"; return 1; } //指定したサービスプロバイダへのTCPソケットを作成する。 const auto sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { cout << "couldn't open a socket.\n"; WSACleanup(); return 1; } //ホスト情報を取得 const auto server_name = "www.kumei.ne.jp"; auto host = gethostbyname(server_name); if (host == nullptr) { auto addr = inet_addr(server_name); host = gethostbyaddr(reinterpret_cast<char*>(&addr), 4, AF_INET); if (host == nullptr) { cout << server_name << " is not found.\n"; WSACleanup(); return 1; } } //IPv4のソケットアドレス情報を設定する sockaddr_in sockadd; memset(&sockadd, 0, sizeof(sockadd)); sockadd.sin_family = AF_INET; sockadd.sin_port = htons(80); sockadd.sin_addr = *(reinterpret_cast<LPIN_ADDR>(*(host->h_addr_list))); //指定したソケットへ接続する if (connect(sock, reinterpret_cast<PSOCKADDR>(&sockadd), sizeof(sockadd)) != 0) { cout << "connect failure.\n"; closesocket(sock); WSACleanup(); return 1; } //メッセージを送信 const string message = "GET /c_lang/index_cp.html HTTP/1.0\r\n\r\n"; const auto res = send(sock, message.c_str(), static_cast<int>(message.size()), 0); if (res == SOCKET_ERROR) { cout << "send failure.\n"; closesocket(sock); WSACleanup(); return 1; } //メッセージを受信 char buf[1024]; while (true) { memset(buf, '\0', sizeof(buf)); auto size = recv(sock, buf, static_cast<int>(sizeof(buf) - 1), 0); cout << buf; //受信が終わったらループを抜ける if (size == 0) { break; } if (size == SOCKET_ERROR) { cout << "recieve error.\n"; break; } } //ソケットの送受信を切断する shutdown(sock, SD_BOTH); //ソケットを破棄する closesocket(sock); //WinSockの解放 WSACleanup(); }
実行結果略
Boost.Asio
#include <boost/asio.hpp> #include <iostream> using namespace std; namespace asio = boost::asio; namespace ip = asio::ip; int main() try { asio::io_service io_service; //TCPソケットを作成する ip::tcp::socket sock(io_service); //名前解決(ホスト名からIPアドレスに変換)する ip::tcp::resolver resolver(io_service); ip::tcp::resolver::query query("www.kumei.ne.jp", "http"); //ホスト情報を設定する ip::tcp::endpoint endpoint(*resolver.resolve(query)); //ソケットへ接続 sock.connect(endpoint); //メッセージを送信 asio::streambuf request; ostream request_ostream(&request); request_ostream << "GET /c_lang/index_cp.html HTTP/1.0\r\n\r\n"; asio::write(sock, request); //メッセージを受信 asio::streambuf buffer; boost::system::error_code error; asio::read(sock, buffer, asio::transfer_all(), error); if (error && error != asio::error::eof) { std::cout << "receive failed: " << error.message() << std::endl; } else { cout << &buffer; } } catch (exception& e) { cout << e.what(); }
実行結果略