This example of this article for you to share the implementation of C + + HTTP server code, for your reference, the specific content as follows
#include <Winsock2.h> #include <windows.h> #include <malloc.h> #include <stdio.h> #include < string.h> #include <time.h> #pragma comment (lib, "ws2_32") #define UPORT #define MAX_BUFFER 100000 #define Sendblock 200000 #define SERVERNAME "acidsoftwebserver/0.1b" #define FILENAME "helloworld.html" typedef struct _N
Ode_ {SOCKET s;
Sockaddr_in Addr;
_node_* Pnext;
}node,*pnode;
Multithreading struct _thread_ {DWORD ThreadID with multiple client-side connection typedef;
HANDLE Hthread;
_thread_* Pnext;
}thread,*pthread;
Pnode phead = NULL;
Pnode ptail = NULL;
PThread pheadthread = NULL;
PThread ptailthread = NULL;
BOOL Initsocket ();//thread function DWORD WINAPI Acceptthread (LPVOID lpparam);
DWORD WINAPI Clientthread (LPVOID lpparam); BOOL Iocomplete (char* szrequest);
The checksum function of the packet is bool Addclientlist (SOCKET s,sockaddr_in addr);
BOOL Addthreadlist (HANDLE Hthread,dword ThreadID);
BOOL Parserequest (char* szrequest, char* szresponse, bool &bkeepalive); We store HTML files in the eyeRecord Char htmldir[512]={0}; void Main () {if (!
Initsocket ()) {printf ("Initsocket error\n");
Return
} getcurrentdirectory (512,htmldir);
strcat (Htmldir, "\\HTML\\");
strcat (Htmldir,filename);
Start an accept thread HANDLE Hacceptthread = CreateThread (null,0,acceptthread,null,0,null);
Here we use the event model to implement our Web server//Create an event WaitForSingleObject (Hacceptthread,infinite); } DWORD WINAPI Acceptthread (LPVOID lpparam)//Receive thread {///create a listener socket socket Slisten = WSASocket (af_inet,sock_stream,0,nu ll,0,wsa_flag_overlapped);
Use event Overlay socket if (slisten==invalid_socket) {printf ("Create Listen error\n");
return-1;
}//Initialize the address of this server sockaddr_in localaddr; Localaddr.sin_addr. S_un.
S_ADDR = Inaddr_any;
localaddr.sin_family = af_inet;
Localaddr.sin_port = htons (Uport);
Binding socket 80-Port int Ret = bind (Slisten, (sockaddr*) &localaddr,sizeof (LOCALADDR));
if (ret==socket_error) {printf ("Bind error\n");
return-1;
}//Monitor listen (slisten,5);
Create an event Wsaevent event = Wsacreateevent ();if (event==wsa_invalid_event) {printf ("Create wsaevent error\n");
Closesocket (Slisten); CloseHandle (Event);
Create event failure close socket Shutdown Event return-1;
///The association of our listener sockets with our events is ACCEPT WSAEventSelect (slisten,event,fd_accept);
Wsanetworkevents networkevent;
Sockaddr_in clientaddr;
int nlen = sizeof (CLIENTADDR);
DWORD dwindex = 0;
while (1) {dwindex = WSAWaitForMultipleEvents (1,&event,false,wsa_infinite,false);
Dwindex = Dwindex-wait_object_0; if (dwindex==wsa_wait_timeout| |
dwindex==wsa_wait_failed) {continue;
///If there is a real event we will judge Wsaenumnetworkevents (Slisten,event,&networkevent); ResetEvent (&event); if (networkevent.lnetworkevents = = fd_accept) {if (networkevent.ierrorcode[fd_accept_bit]==0) {//We are going to make a new
Connect to accept and request memory deposit in the list SOCKET sclient = Wsaaccept (Slisten, (sockaddr*) &clientaddr, &nlen, NULL, NULL);
if (Sclient==invalid_socket) {continue; else {//if received successfully we want to store all the information of the user in the list if (! ADdclientlist (SCLIENT,CLIENTADDR)) {continue;
return 0,}}}}
} DWORD WINAPI Clientthread (lpvoid lpparam) {//We pass each user's information as a parameter to the thread pnode ptemp = (pnode) Lpparam; SOCKET sclient = ptemp->s; This is the communication socket wsaevent Event = Wsacreateevent ();
The event is associated with a communication socket to determine the type of event wsanetworkevents networkevent; Char szrequest[1024]={0}; Request message Char szresponse[1024]={0}; Response message BOOL bkeepalive = FALSE;
Whether continuous connection if (Event = = wsa_invalid_event) {return-1; int Ret = WSAEventSelect (sclient, Event, Fd_read | Fd_write | Fd_close);
Associated event and socket DWORD dwindex = 0;
while (1) {dwindex = WSAWaitForMultipleEvents (1,&event,false,wsa_infinite,false);
Dwindex = Dwindex-wait_object_0; if (dwindex==wsa_wait_timeout| |
dwindex==wsa_wait_failed) {continue;
}//analyze what network events Generate Ret = Wsaenumnetworkevents (sclient,event,&networkevent); Other cases if (!
Networkevent.lnetworkevents) {continue; } if (Networkevent.lnetworkevents & Fd_read)//This is very intentional.Think of {DWORD numberofbytesrecvd;
WSABUF buffers;
DWORD dwbuffercount = 1;
Char Szbuffer[max_buffer];
DWORD Flags = 0;
Buffers.buf = Szbuffer;
Buffers.len = Max_buffer;
Ret = WSARecv (sclient,&buffers,dwbuffercount,&numberofbytesrecvd,&flags,null,null);
We are here to detect whether a complete request is received memcpy (SZREQUEST,SZBUFFER,NUMBEROFBYTESRECVD); if (!
Iocomplete (Szrequest))//checksum packet {continue; } if (!
Parserequest (Szrequest, Szresponse, bkeepalive))//Analysis Packet {//I am here to do a simple processing continue;
} DWORD numberofbytessent = 0;
DWORD dwbytessent = 0; Send response to client do {Buffers.len = (strlen (szresponse)-dwbytessent) >= Sendblock?
Sendblock:strlen (szresponse)-dwbytessent;
Buffers.buf = (char*) ((DWORD) szresponse + dwbytessent);
Ret = WSASend (Sclient, &buffers, 1, &numberofbytessent,
0, 0, NULL); if (socket_error!= Ret) dwbytessent + = numberofbytessent;
while ((Dwbytessent < strlen (szresponse)) && socket_error!= Ret);
} if (Networkevent.lnetworkevents & fd_close) {//Here I do not handle, we want to release the memory otherwise memory leaks}} return 0;
BOOL Initsocket () {wsadata wsadata;
if (Makeword (2,2), &wsadata) ==0)//You must invoke the parameter action return value {True When you use the socket WSAStartup;
return false;
BOOL Addclientlist (SOCKET s,sockaddr_in addr) {Pnode ptemp = (pnode) malloc (sizeof (Node));
HANDLE hthread = NULL;
DWORD ThreadID = 0;
if (ptemp==null) {printf ("No memory\n");
return false;
else {ptemp->s = s;
PTEMP->ADDR = Addr;
Ptemp->pnext = NULL;
if (phead==null) {phead = Ptail = ptemp;
else {ptail->pnext = ptemp;
Ptail = ptail->pnext;
//We want to open a new thread for the user Hthread = CreateThread (Null,0,clientthread, (LPVOID) ptemp,0,&threadid);
if (hthread==null) {free (ptemp);
return false; } if (! AddthreadList (Hthread,threadid)) {free (ptemp);
return false;
} return true;
BOOL Addthreadlist (HANDLE Hthread,dword ThreadID) {pThread ptemp = (pThread) malloc (sizeof (Thread));
if (ptemp==null) {printf ("No memory\n");
return false;
else {ptemp->hthread = Hthread;
Ptemp->threadid = ThreadID;
Ptemp->pnext = NULL;
if (pheadthread==null) {pheadthread = Ptailthread = ptemp;
else {ptailthread->pnext = ptemp;
Ptailthread = ptailthread->pnext;
} return true; }//Checksum packet bool Iocomplete (char* szrequest) {char* ptemp = NULL; Defines a temporary null pointer int nlen = strlen (szrequest);
Request Packet Length ptemp = szrequest; Ptemp = ptemp+nlen-4;
The position pointer if (strcmp (ptemp, "\r\n\r\n") ==0)//Verify the carriage return control and newline characters at the end of the header line and the blank line {true;
return false;
}//Analysis packet bool Parserequest (char* szrequest, char* szresponse, bool &bkeepalive) {char* p = NULL;
p = szrequest;
int n = 0; char* ptemp = Strstr (P, ""); Determines whether the string str2 is a str1 substring. If yes, then the letterNumber returns the address of the first occurrence of str2 in str1, otherwise, returns NULL. n = ptemp-p; Pointer length//ptemp = ptemp + n-1;
Move our pointer down//define a temporary buffer to store our char szmode[10]={0};
Char szfilename[10]={0}; memcpy (Szmode,p,n);
Copies the request method to the Szmode array if (strcmp (Szmode, "get") ==0)//must be written in uppercase {//obtain filename Ptemp = strstr (Ptemp, ""); Ptemp = ptemp + 1;
Only when debugging can find the secret memcpy (szfilename,ptemp,1);
if (strcmp (szFileName, "/") ==0) {strcpy (szfilename,filename);
else {return false;
} else {return false; }//Analysis link Type ptemp = strstr (szrequest, "\nconnection:keep-alive");
Protocol version n = ptemp-p;
if (p>0) {bkeepalive = TRUE;
else//The setting here is for the proxy program to run {bkeepalive = TRUE;
//define a echo header char presponseheader[512]={0};
Char szstatuscode[20]={0};
Char szcontenttype[20]={0};
strcpy (Szstatuscode, "OK");
strcpy (Szcontenttype, "text/html");
Char szdt[128];
struct TM *newtime;
Long Ltime;
Time (<ime);
NewTime = Gmtime (<ime); Strftime (SZDT, 128, "%a,%d%b%Y%h:%m:%s GMT", newtime);
Read files//define a file stream pointer file* fp = fopen (Htmldir, "RB");
fpos_t lengthactual = 0;
int length = 0;
char* buffertemp = NULL;
if (fp!=null) {//Get file size fseek (FP, 0, Seek_end);
Fgetpos (FP, &lengthactual);
Fseek (FP, 0, Seek_set);
After calculating the size of the file we allocate memory Buffertemp = (char*) malloc (sizeof (char) * ((int) lengthactual));
Length = Fread (buffertemp,1, (int) LENGTHACTUAL,FP);
Fclose (FP); Return response sprintf (Presponseheader, "http/1.0%s\r\ndate:%s\r\nserver:%s\r\naccept-ranges:bytes\r\ncontent-length:%d\ R\nconnection:%s\r\ncontent-type:%s\r\n\r\n ", Szstatuscode, SZDT, SERVERNAME, length, bkeepalive? "Keep-alive": "Close", Szcontenttype);
Response message}//If our files are not found we will lead the user to another error page else {} strcpy (Szresponse,presponseheader);
strcat (szresponse,buffertemp);
Free (buffertemp);
Buffertemp = NULL;
return true; }
The above is the entire content of this article, I hope to help you learn.