UNP 学习笔记2

来源:互联网 发布:下载itunes软件 编辑:程序博客网 时间:2024/05/01 07:37

4.实现一个简单的httpserver,仅支持get

#include <sys/socket.h>#include <unistd.h>#include <errno.h>#include <netinet/in.h>#include <string.h>#include <stdio.h>#define BUF_LEN 1028#define SERVER_PORT 8080const static char http_error_hdr[] = "HTTP/1.1 404 Not Found\r\nContent-type: text/html\r\n\r\n";const static char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";const static char http_html_index[] = "<html><head><title>Congrats!</title></head>""<body><h1>Welcome to our HTTP server !</h1>""<p>This is a test page.</body></html>";/* step to socket programming: * * 1. call socket(int family, int type, int protocol), set I/O protocol : IPv4TCP/IPv6UDP/.. *family:type:protocol: *AF_INET: IPv4SOCK_STREAM: byte streamIPPROTO_CP: TCP *AF_INET6: IPv6SOCK_DGREAM: data gramIPPROTO_UDP: UDP *AF_LOCAL: unix...IPPROTO_SCTP: SCTP *return sockfd : socket descriptor * * 2. bind() assgin a local protocol address to an unamed socket * * 3. listen(int sockfd, int backlog) called by server *    backlog deciede the size of queue. *it has two queue: incomplete connection queue/ completed connection queue * * 4. accept() */int http_send_file(char* filename, int sockfd){if (!strcmp(filename, "/")) {write(sockfd, http_html_hdr, strlen(http_html_hdr));write(sockfd, http_html_index, strlen(http_html_index));}else {printf("%s: file not find!\n", filename);write(sockfd, http_error_hdr, strlen(http_html_hdr));}return 0;}// HTTP analyse requestvoid analyse(int sockfd) {char buf[BUF_LEN];read(sockfd, buf, BUF_LEN);if (!strncmp(buf, "GET", 3)) {char *file = buf + 4;char *space = strchr(file, ' ');*space = '\0';http_send_file(file, sockfd);}else {printf("unsupported request!\n");}}int main(){int sockfd, err, newfd; // socket descripestruct sockaddr_in addr;sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {perror("socket creation failed!\n");return -1;}memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;// host to net work longaddr.sin_port = htons(SERVER_PORT);addr.sin_addr.s_addr = INADDR_ANY;if (bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))) {perror("socket binding failed!\n");return -1;}listen(sockfd,128);for (;;) {newfd = accept(sockfd, NULL, NULL);analyse(newfd);close(newfd);}}

5.用fork()实现并发的服务器
unistd.h提供的fork()函数可以简单地将原来的单线程单进程阻塞的server改为多进程的server

fork()函数的特点在于,调用一次,它会返回两次,在子进程返回0,父进程返回子进程id,出错返回-1

if (pid = fork() < 0) {perror("error");}else if (pid == 0) {//childprocess do;}else {//parentprocess do;}

这样的一个结构就可以帮助我们实现一个简单的多进程并发server

#include <sys/socket.h>#include <unistd.h>#include <errno.h>#include <netinet/in.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#define BUF_LEN 1024#define Q_LEN 128#define SERVER_PORT 8080const static char http_error_hdr[] = "HTTP/1.1 404 Not Found\r\nContent-type: text/html\r\n\r\n";const static char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";const static char http_html_index[] = "<html><head><title>Congrats!</title></head>""<body><h1>Welcome to our HTTP server !</h1>""<p>This is a test page.</body></html>";int http_send_file(char* filename, int sockfd){if (!strcmp(filename, "/")) {write(sockfd, http_html_hdr, strlen(http_html_hdr));write(sockfd, http_html_index, strlen(http_html_index));}else {printf("%s: file not find!\n", filename);write(sockfd, http_error_hdr, strlen(http_html_hdr));}return 0;}// HTTP analyse requestvoid analyse(int sockfd) {char buf[BUF_LEN];read(sockfd, buf, BUF_LEN);if (!strncmp(buf, "GET", 3)) {char *file = buf + 4;char *space = strchr(file, ' ');*space = '\0';http_send_file(file, sockfd);}else {printf("unsupported request!\n");}}int main(int argc, char **argv){int listenfd, connfd;pid_t childpid;socklen_t clilen;struct sockaddr_in cliaddr, servaddr;listenfd = socket(AF_INET, SOCK_STREAM, 0);if (listenfd < 0) {perror("socket creation failed!\n");return -1;}bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = INADDR_ANY;servaddr.sin_port = htons(SERVER_PORT);if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) {perror("socket bindinf failed!\n");return -1;}listen(listenfd, Q_LEN);for ( ; ; ) {clilen = sizeof(cliaddr);connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);if (connfd < 0) {perror("scoket accept failed!\n");}if ( (childpid = fork()) == 0) {close(listenfd);analyse(connfd);exit(0);}close(connfd);}}


0 0
原创粉丝点击