http server

An http server is a program running on a host computer. After the program is started, it will always wait for requests from all other users. After receiving the request, it will process the request and send a response to the client. The HTTP protocol is used for communication between the client and the server, and all programs that follow the HTTP protocol can act as clients.

socket socket:

int socket(int family,int type,int protocol);

  • family: protocol family. AF_INET: IPV4 protocol; AF_INET6: IPv6 protocol; AF_LOCAL: Unix domain protocol; AF_ROUTE: routing socket; AF_KEY: key socket
  • type: socket type. SOCK_STREAM: byte stream socket; SOCK_DGRAM: packet socket; SOCK_SEGPACKET: ordered packet socket; SOCK_RAW: raw socket
  • protocol: A protocol type constant. TCP: 0, UDP: 1, SCTP: 2

Socket address structure:

In socket programming, most functions use a pointer to the socket geological structure as a parameter. For different protocol types, there will be different structure definition formats. For iPv4, the structure is as follows: 

struct sockaddr_in {
     uint8_t sin_len; /* Length of structure */
     sa_family_t sin_family; /* IP protocol family, IPV4 is AF_INET */
     in_port_t sin_port; /* A 16-bit TCP/UDP port address */
     struct in_addr sin_addr; /* 32-bit IPV4 address, network byte order */
     char sin_zero[8]; /* unused field*/
}; Note: sockaddr_in is the abbreviation of **Internet socket address structure**.

ip address structure:

struct in_addr{
in_addr_t  s_addr;
}

 The function of the address structure of the socket is to pass the IP address and port number to the socket function, and the way of writing the structure is for abstraction. When party is passed as an argument to any socket function, the socket address structure is always passed by reference. However, there are many protocol families, so any socket function that takes such a pointer as one of the parameters must handle socket address structures from all supported protocol families. Use void* as the generic pointer type, so the socket function is defined to take a pointer to some generic socket structure as one of its arguments

int bind(int ,struct sockaddr* ,socklen_t)

This requires that any call to these functions must cast a pointer to a protocol-specific socket's address structure to a pointer to some generic socket's structure.

struct sockaddr_in addr;

bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));

As with all socket functions, the only use of sockaddr is to perform a cast on a pointer to a socket structure for a specific protocol, only the protocol address of the socket to which it is bound.

 

bind function: Bind the socket address structure to the socket.

int bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));

After binding the socket, you can use the socket to start listening for requests.

listen function:

Converts a sockfd unconnected socket into a passive socket, indicating that the kernel should accept connection requests directed to this socket.

int listen(int sockfd,int backlog);

Regarding the backlog parameter, the kernel maintains two queues for any given listening socket: 1. the queue that has not completed, and 2. the queue that has completed

The sum of the 2 queues does not exceed the size of the backlog.

After the listen is completed, the socket is in the llisten state, and the socket at this time can receive the request from the client by calling the accept function.

 

accept函数
int accept(int sockfd,struct sockaddr*clientaddr,socklen_t *addrlen);

The first parameter sockfd is the client's socket description, the second is the client's socket address, and the third is the length of the socket address structure.

If accept is successful, the return value is a brand new descriptor generated by the kernel representing the returned TCP connection.

After the accept function, a TCP connection is resumed, and then the server accepts the client's request information, and then responds.

recv and send functions:

ssize_t recv(int sockfd,void* buff,size_t nbytes,int flags);

ssize_t send(int sockfd,const void* buff,size_t nbytes,int flags);

Read information from the client and send information to the client, respectively.

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>

#define PORT 9001
#define QUEUE_MAX_COUNT 5
#define BUFF_SIZE 1024

#define SERVER_STRING "Server : hoohackhttp/0.1.0\r\n"
 
int main(){
	int server_fd = -1;
	int client_fd = -1;
	
	u_short port = PORT;
	struct sockaddr_in client_addr;
	struct sockaddr_in server_addr;
	socklen_t client_addr_len = sizeof(client_addr);
	
	char buf[BUFF_SIZE];
	char recv_buf[BUFF_SIZE];
	char hello_str[] = "hello world!";
	
	int hello_len = 0;
	
	//create a socket
	server_fd = socket (AF_IINET, SOCK_STREAM, 0);
	if(server_fd == -1){
		perror("socket");
		exit(-1);
	}
	memset(&server_addr,0,sizeof(server_addr));
	
	//Set the port, ip and tcpip protocol family
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	// bind socket to port
	if(bind(server_fd,(struct sockaddr*)&server_addr),sizeof(server_addr)<0){
		perror("bind");
		exit(-1);
	}
	
	//Start the socket to listen for requests and start waiting for client requests
	if(listen(server_fd,QUEUE_MAX_COUNT)<0){
		perror("listen");
		exit(-1);
	}
	
	printf("http server running on port %d",port);
	
	while(1){
		//Call the accept function, blocking the program until the client's request is received
		client_fd = accept(server_fd,(struct sockaddr*)&client_addr,&client_addr_len);
		if(client_fd <0){
			perror("accept");
			exit(-1);
		}
		printf("accept a client\n");
		
		printf("client socket fd :%d\n",client_fd);
		hello_len = recv(client_fd,recv_buf,BUFF_SIZE,0)
		printf("receive %d\n",hello_len);
		
		// send response to client
		sprintf(buf,"http/1.0 200 ok \r\n");
		send(client_fd,buf,strlen(buf),0);
		strcpy(buf,SERVER_STRING);
		send(client_fd,buf,strlen(buf),0);
		sprintf(buf,"content-type:text/html\r\n");
		send(client_fd,buf,strlen(buf),0);
		strcpy(buf,"\r\n");
		send(client_fd,buf,strlen(buf),0);
		sprintf(buf,"hello world\r\n");
		send(client_fd,buf,strlen(buf),0);
		
		//Close the client socket
		close(server_fd);
		return 0;
	}
	
	 
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324927678&siteId=291194637