C++ Winsock Basic HTTP Connection
I had some unix socket code that I was working with, and I needed to convert it to run on windows. Thanks to a handy Windows Socket PDF, I was able to get some basic code going.
This is not meant to be 'production' level stuff... merely a hello world of using winsock. One of the things I did not account for in this code was download lag. For instance, if you are downloading a 40kb page it may take a few seconds. What happens is the recv() function can only access data that has already been downloaded, so this code will end an http download 'early' if the download is anything slower than instant.
#include <iostream> #include <string> #include <stdlib.h> #include <winsock.h>//dont forget to add wsock32.lib to linker dependencies using namespace std; #define BUFFERSIZE 1024 void die_with_error(char *errorMessage); void die_with_wserror(char *errorMessage); int main(int argc, char *argv[]) { string request; string response; int resp_leng; char buffer[BUFFERSIZE]; struct sockaddr_in serveraddr; int sock; WSADATA wsaData; char *ipaddress = "208.109.181.178"; int port = 80; request+="GET /test.html HTTP/1.0\r\n"; request+="Host: www.zedwood.com\r\n"; request+="\r\n"; //init winsock if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) die_with_wserror("WSAStartup() failed"); //open socket if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) die_with_wserror("socket() failed"); //connect memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = inet_addr(ipaddress); serveraddr.sin_port = htons((unsigned short) port); if (connect(sock, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) die_with_wserror("connect() failed"); //send request if (send(sock, request.c_str(), request.length(), 0) != request.length()) die_with_wserror("send() sent a different number of bytes than expected"); //get response response = ""; resp_leng= BUFFERSIZE; while (resp_leng == BUFFERSIZE) { resp_leng= recv(sock, (char*)&buffer, BUFFERSIZE, 0); if (resp_leng>0) response+= string(buffer).substr(0,resp_leng); //note: download lag is not handled in this code } //display response cout << response << endl; //disconnect closesocket(sock); //cleanup WSACleanup(); return 0; } void die_with_error(char *errorMessage) { cerr << errorMessage << endl; exit(1); } void die_with_wserror(char *errorMessage) { cerr << errorMessage << ": " << WSAGetLastError() << endl; exit(1); }
code snippets are licensed under Creative Commons CC-By-SA 3.0 (unless otherwise specified)
Digital Picture Frames
on
2011-07-14 03:33:21
I find this article from google, it’s really useful for me, hope I can post this in my blog. nice post , I will share with my friends: )
|
daniel
on
2011-08-02 11:44:08
What if the amount of bytes returned is exactly the size of the buffer? Wouldn't recv block? (That's what happens to me)
|
nefton
on
2013-11-01 22:28:09
thanx
|
DWW
on
2016-07-30 17:27:21
This is crazy man! <h1>Wow</h1>
|
Dev
on
2016-08-07 14:12:36
Instead of adding wsock32.lib to build dependencies just do:
#pragma comment(lib,"wsock32") |