C language-implemented Web server

Source: Internet
Author: User
Tags parse error socket error strcmp

/**************filename:server.cpp****************
The program implements a simple HTTP server through a standard socket
Running the server can access the server directory through the browser
HTML files and JPG Images complete the initial HTTP server functionality
***************************************************/
#include <winsock.h>
#include <sys/stat.h>
#include <iostream>
using namespace Std;
#define SERVER_PORT 10000//Custom service port
#define HOSTLEN 256//Host name length
#define BACKLOG 10//number of simultaneous waiting connections
/**************************************
The method wraps the Send ()
Sending the data through this method can all be emitted
No omissions.
**************************************/
int Sendall (int s, char *buf, int *len) {
int total = 0; Number of bytes already sent
int bytesleft = *len; How many bytes are left?
int n;
while (Total < *len) {
n = Send (S, buf+total, Bytesleft, 0);
if (n = =-1) {break;}
Total + = n;
Bytesleft-= n;
}
*len = total; Returns the number of bytes actually sent out
return n==-1?-1:0; Successful send returned 0 failed-1
}
/**************************************
The method handles the error request
and sends an error message to the client
**************************************/
void Wrong_req (int sock) {
char* error_head = "http/1.0 501 not implemented\r\n"; Output 501 Error
int len = strlen (Error_head);
if (Sendall (sock, error_head, &len) = =-1) {//Send to Customer
printf ("Sending failed!");
Return
}
char* Error_type = "content-type:text/plain\r\n";
Len = strlen (Error_type);
if (Sendall (sock, error_type, &len) = =-1) {
printf ("Sending failed!");
Return
}
char* error_end = "\ r \ n";
Len = strlen (error_end);
if (Sendall (sock, error_end, &len) = =-1) {
printf ("Sending failed!");
Return
}
char* prompt_info = "The command is not yet completed\r\n";
Len = strlen (prompt_info);
if (Sendall (sock, prompt_info, &len) = =-1) {
printf ("Sending failed!");
Return
}
}
/**********************************
This method determines whether the file requested by the user exists
Not present returns True existence returns False
***********************************/
BOOL Not_exit (char* arguments) {
struct stat dir_info;
Return (stat (arguments, &dir_info) = =-1);
}
/*************************************
The requested file does not exist
*************************************/
void File_not_found (char* arguments, int sock) {
char* error_head = "http/1.0 404 Not Found\r\n"; Construct 404 Error head
int len = strlen (Error_head);
if (Sendall (sock, error_head, &len) = =-1) {//Send to Client
printf ("Sending error!");
Return
}
char* Error_type = "content-type:text/plain\r\n";
Len = strlen (Error_type);
if (Sendall (sock, error_type, &len) = =-1) {
printf ("Sending error!");
Return
}
char* error_end = "\ r \ n";
Len = strlen (error_end);
if (Sendall (sock, error_end, &len) = =-1) {
printf ("Sending error!");
Return
}
Char prompt_info[50] = "not Found:";
strcat (prompt_info, arguments);
Len = strlen (prompt_info);
if (Sendall (sock, prompt_info, &len) = =-1) {//Output files not found
printf ("Sending error!");
Return
}
}
/*************************************
Send HTTP protocol header information
These include the response type and the content type
*************************************/
void Send_header (int send_to, char* content_type) {

char* head = "http/1.0 ok\r\n"; The right header information
int len = strlen (head);
if (Sendall (send_to, head, &len) = =-1) {//Send data to the connected client
printf ("Sending error");
Return
}
if (content_type) {//content_type is not empty
Char temp_1[30] = "Content-type:"; Prepare the string you want to connect to
strcat (Temp_1, Content_Type); Construction Content_Type
strcat (temp_1, "\ r \ n");
Len = strlen (temp_1);
if (Sendall (send_to, temp_1, &len) = =-1) {
printf ("Sending error!");
Return
}
}
}
/***********************************
Get the file type requested by the user
That is, the file suffix (. html. jpg. gif)
************************************/
char* File_type (char* Arg) {
char * TEMP; Temporary string pointer
if (TEMP=STRRCHR (ARG, '. ')) = NULL) {//Get suffix
return temp+1;
}
Return ""; If the file name is not in the request. The empty string is returned
}
/*************************************
This method is the core of the program
Responsible for really sending files such as *.html *.jpg etc.
*************************************/
void Send_file (char* arguments, int sock) {
char* extension = file_type (arguments); Get the file suffix name
char* content_type = "Text/plain"; Initialize type= ' Text/plain '
File* Read_from; The local file pointer reads from the file. html. jpg, etc.
int readed =-1; Number of bytes per read

if (strcmp (extension, "html") = = = 0) {//Send content as HTML
Content_Type = "text/html";
}
if (strcmp (extension, "gif") = = 0) {//Send content as GIF
Content_Type = "Image/gif";
}
if (strcmp (extension, "jpg") = = = 0) {//send content as JPG
Content_Type = "Image/jpg";
}
Read_from = fopen (arguments, "R"); Open user-specified file ready to read
if (read_from! = NULL) {//Pointer not empty
Char read_buf[128]; Byte Cache array when reading a file
Send_header (sock, Content_Type); Send Protocol Header
Send (sock, "\ r \ n", 2, 0); Add a "\ r \ n" cannot lack the format requirement
while (!feof (Read_from)) {//Determines whether the file has ended
Fgets (Read_buf, Read_from); Read
int len = strlen (READ_BUF);
if (Sendall (sock, read_buf, &len) = =-1) {//Send data
printf ("Sending error!"); A send error appears to the console to continue sending
Continue
}
}
}
}
/***********************************
Parse and process user requests
***********************************/
void Handle_req (char* request, int client_sock) {
Char Command[bufsiz]; Save resolved to a command field get PUT
Char Arguments[bufsiz]; Save the file to which the request was resolved
/*
* Add the current directory symbol before user request
*/
strcpy (arguments, "./"); Note the difference between the symbols in different operating systems
/*
* Parse Request
*/
if (sscanf (Request, "%s%s", command, arguments+2)! = 2) {
Return Parse Error in return
}

printf ("Handle_cmd:%s\n", command); Output This command to the console
printf ("Handle_path:%s\n", arguments); To output the request path at this time to the console

if (strcmp (command, "GET")! = 0) {//Request command format is correct
Wrong_req (Client_sock);
Return
}
if (not_exit (arguments)) {//The requested file exists
File_not_found (arguments, client_sock);
Return
}
Send_file (arguments, client_sock); Send data when command format and request path are correct

Return
}
/*************************************
This method constructs a server-side socket
Returns the constructed socket descriptor
*************************************/
int Make_server_socket () {
struct sockaddr_in server_addr; Server address structure body
int tempsockid; Temporarily store the socket descriptor
Tempsockid = socket (pf_inet, sock_stream, 0);

if (Tempsockid = =-1) {//error if return value is-1
return-1;
}
/*
* Populate Server connection information
*/
server_addr.sin_family = af_inet;
Server_addr.sin_port = htons (Server_port);
SERVER_ADDR.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1"); Local address
memset (& (Server_addr.sin_zero), ' + ', 8);
if (bind (tempsockid, struct sockaddr *) &server_addr,
sizeof (SERVER_ADDR)) = =-1) {//Bind service returns 1 if an error occurs
printf ("Bind error!\n");
return-1;
}
if (Listen (Tempsockid, BACKLOG) = =-1) {//start listening
printf ("Listen error!\n");
return-1;
}
return tempsockid; Returns the socket obtained
}
/***********************
Main function Main ()
Program entry
***********************/
void Main (int argc, char * argv[]) {
/*
* Call WSAStartup () for easy access to sockets library
*/
Wsadata Wsadata;
if (WSAStartup (Makeword (1, 1), &wsadata)! = 0) {
fprintf (stderr, "WSAStartup failed.\n");
Exit (1);
}
printf ("My Web server started...\n");
int server_socket; Socket for server
int acc_socket; The socket that receives the user connection
int sock_size = sizeof (struct sockaddr_in);
struct sockaddr_in user_socket; Customer connection Information
Server_socket = Make_server_socket (); Create a server-side socket
if (Server_socket = =-1) {//Create socket Error
printf ("Server exception!\n");
Exit (2);
}
/*
* Main loop
*/
while (true) {
Acc_socket = Accept (Server_socket, (struct sockaddr *) &user_socket, &sock_size); Receive connection

cout << Inet_ntoa (user_socket.sin_addr) << Endl; Test with:-)//

/*
* Read Customer Request
*/
int numbytes;
Char buf[100];
if ((Numbytes=recv (Acc_socket, buf, 99, 0)) = =-1) {
Perror ("recv");
Exit (1);
}

printf ("Buf ...%s", buf); For testing
/*
* Processing user requests
*/
Handle_req (buf, Acc_socket);
}
}
/************** Program End server.cpp******************/

C language-implemented Web server

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.