Hypertext Transfer Protocol (HTTP) is a communication protocol that allows the transfer of Hypertext Markup Language (HTML) documents from a Web server to a web browser. HTML is a markup language used to create documents that contain links to relevant information. You can click a link to access other documents, images, or multimedia objects and obtain additional information about the link items. Both the client and server must support HTTP to send and receive HTML documents and interact with each other on the World Wide Web.
HTTP is an object-oriented protocol at the application layer. It is applicable to distributed hypermedia information systems due to its simple and fast method. It proposed in 1990 that, after several years of use and development, it has been continuously improved and expanded. Currently, the sixth version of HTTP/1.0 is used in WWW, especially on the proxy server. Standardization of HTTP/1.1 is in progress, persistent connections are used by default, and can work well with the proxy server. And the recommendations for HTTP-NG (Next Generation of HTTP) have been put forward.
The main features of HTTP are as follows:
Supports the customer/Server mode. Simple and fast: when a customer requests a service from the server, only the Request Method and path are required. Common Request methods include get, Head, and post. Each method specifies the type of contact between the customer and the server. Because the HTTP protocol is simple, the program size of the HTTP server is small, so the communication speed is fast. Flexible: HTTP allows transmission of any type of data objects. The type being transferred is marked by Content-Type. No connection: No connection means that only one request is allowed for each connection. After the server processes the customer's request and receives the customer's response, the connection is disconnected. This method can save transmission time. Stateless: HTTP is stateless. Stateless means that the Protocol has no memory for transaction processing. The lack of status means that if subsequent processing requires the previous information, it must be re-transmitted, which may increase the amount of data transmitted each connection. On the other hand, when the server does not need previous information, its response is faster.
Let's use VC ++ to implement the HTTP protocol.
# Include <stdio. h >#include <winsock2.h> # define maxbuflen 20480 # define httpaddlen 50 # define timewait 2000 # pragma comment (Lib, "ws2_32.lib") socket global [1000]; DWORD winapi proxy (lpvoid psocket); int parsehttprequest (char * sourcebuf, int datalen, void * serveraddr); int main (INT argc, char * argv []) {socket mainsocket, clientsocket; struct sockaddr_in host, client; wsadata; int addlen, I ;/ /Initialize if (wsastartup (makeword (2, 2), & wsadata) <0) {printf ("initialization failed \ n"); return 1 ;} // create the socket port mainsocket = socket (af_inet, sock_stream, ipproto_tcp); If (mainsocket = socket_error) {printf ("port creation error \ n"); return 1 ;} host. sin_family = af_inet; host. sin_port = htons (8080); host. sin_addr.s_addr = inet_addr ("127.0.0.1"); printf ("working \ n"); // bind socket If (BIND (mainsocket, (sockaddr *) & host, sizeof (host ))! = 0) {printf ("binding error \ n");} I = 0; // listen if (Listen (mainsocket, 5) = socket_error) {printf ("listener error \ n");} addlen = sizeof (client); // connect to a new client I = 0; (;;) {clientsocket = accept (mainsocket, (sockaddr *) & client, & addlen); If (clientsocket = socket_error) {printf ("client request accepted error! \ N ");} printf (". "); I ++; if (I >= 1000) I = 0; global [I] = clientsocket; // control the startup of different threads for each customer. // when using clientsocket, do you want to ensure that only one process can be used at a certain time? Createthread (null, 0, proxy, (lpvoid) Global [I], 0, null);} return 0;} DWORD winapi proxy (lpvoid psocket) {socket clientsocket; char receivebuf [maxbuflen]; int datalen; struct sockaddr_in serveraddr; socket proxysocket; int I = 0; int time = timewait; // obtain the port number information in the parameter clientsocket = (socket) psocket; // accept the first request message memset (receivebuf, 0, maxbuflen); datalen = Recv (clientsocket, receivebuf, maxbuflen, 0); If (datal En = socket_error) {printf ("error \ n"); closesocket (clientsocket); Return 0 ;}if (datalen = 0) {closesocket (clientsocket ); return 0;} // process the request information and extract the server address if (parsehttprequest (receivebuf, datalen, (void *) & serveraddr) <0) {closesocket (clientsocket ); goto error;} // create a new socket to connect with the server. proxysocket = socket (af_inet, sock_stream, ipproto_tcp); // set the timeout value setsockopt (proxysocket, sol_socket, so_rcvtimeo, (char *) & Time, sizeof (time); If (proxysocket = socket_error) {printf ("port creation error \ n"); Return 0;} If (connect (proxysocket, (sockaddr *) & serveraddr, sizeof (serveraddr) = socket_error) {// printf ("connection server error"); goto error ;} // start data transmission processing // send it to the server if (send (proxysocket, receivebuf, datalen, 0) = socket_error) {// printf ("data sending error "); goto error;} // receives data from the server while (datalen> 0) {memset (receivebuf, 0, maxbuflen); If (DA Talen = Recv (proxysocket, receivebuf, maxbuflen, 0) <= 0) {// printf ("data receipt error"); break ;} else // send to client if (send (clientsocket, receivebuf, datalen, 0) <0) {// printf ("data sending error"); break ;}} error: closesocket (clientsocket); closesocket (proxysocket); Return 0;} int parsehttprequest (char * sourcebuf, int datalen, void * serveraddr) {char * httphead = "http ://"; char * firstlocation = NULL; char * lastloca Tion = NULL; char * portlocation = NULL; char servername [httpaddlen]; char portstring [10]; int namelen; struct hostent * phost; struct sockaddr_in * pserver = (struct sockaddr_in *) serveraddr; // get http: // location firstlocation = strstr (sourcebuf, httphead) + strlen (httphead); // get/location printf ("% s \ n ", firstlocation); lastlocation = strstr (firstlocation, "/"); // get the name memset (servername, 0, httpadd Len); memcpy (servername, firstlocation, lastlocation-firstlocation); // in some cases, the request address contains the port number format: + port number; // get: location portlocation = strstr (servername, ":"); // fill in the server structure pserver-> sin_family = af_inet; // specify the server port if (portlocation! = NULL) {namelen = portlocation-servername-1; memset (portstring, 0, 10); memcpy (portstring, portlocation + 1, namelen); pserver-> sin_port = htons (u_short) atoi (portstring); * portlocation = 0;} else // in the URL, no server port is specified. {pserver-> sin_port = htons (80 );} if (namelen> httpaddlen) {printf ("the server name is too long \ n"); Return-1 ;}// obtain the server information // if the address information is IP address (192.168.0.1) if (servername [0]> = '0' & servername [0] <= '9 ') {Pserver-> sin_addr.s_addr = inet_addr (servername);} // The else {phost = (struct hostent *) gethostbyname (servername) that appears in the form of a domain name (www.sina.com.cn ); if (! Phost) {printf ("failed to get host information \ n"); printf ("% s \ n", servername); Return-1;} memcpy (& pserver-> sin_addr, phost-> h_addr_list [0], sizeof (pserver-> sin_addr);} return 0 ;}