1 #include <stdio.h>
2 #include <pthread.h>
3 #include <strings.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <fcntl.h>
12 char err[] = "HTTP/1.1 404 Not Found\r\n"
13 "Content-Type: text/html\r\n"
14 "\r\n"
15 "<HTML><BODY>File not found</BODY></HTML>";
16 char head[] = "HTTP/1.1 200 OK\r\n"
17 "Content-Type: text/html\r\n"
18 "\r\n";
19 // 线程
20 void *recv_send_fun(void *arg)
21 {
22 int sockfd_new = *((int *)arg);
23 char buf[1024] = "";
24 char filebuf[1024] = "";
25 char file[64] = "";
26 int fd = 0;
27 int len = 0;
28 while (1)
29 {
30 bzero(buf, sizeof(buf));
31 bzero(file, sizeof(file));
32 // 接受浏览器发来的消息
33 recv(sockfd_new, buf, sizeof(buf), 0);
34 // 解析浏览器请求文件
35 sscanf(buf, "GET /%s", file);
36 fd = open(file, O_RDWR);
37 if (fd > 0) // 判断文件是否存在
38 {
39 send(sockfd_new, head, strlen(head), 0);
40 while (1)
41 {
42 len = read(fd, filebuf, sizeof(filebuf));
43 send(sockfd_new, filebuf, len, 0);
44 if (len < 1024)
45 break;
46 }
47 }
48 else
49 {
50 send(sockfd_new, err, strlen(err), 0);
51 }
52 }
53 return NULL;
54 }
55
56 int main(int argc, char const *argv[])
57 {
58 // 1.创建套接字
59 int sockfd = socket(AF_INET, SOCK_STREAM, 0);
60 if (sockfd < 0)
61 {
62 perror("socket");
63 return -1;
64 }
65 // 2.端口复用
66 int yes = 1;
67 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
68 // 3.绑定
69 struct sockaddr_in my_addr;
70 my_addr.sin_family = AF_INET;
71 my_addr.sin_port = htons(8000);
72 my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
73 int ret = bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
74 if (ret != 0)
75 {
76 perror("bind");
77 return -1;
78 }
79 // 4.监听
80 listen(sockfd, 10);
81
82 struct sockaddr_in cli_addr;
83 int len = sizeof(cli_addr);
84 char ip[16] = "";
85 unsigned short port = 0;
86 int sockfd_new = 0;
87 while (1)
88 {
89 // 5.保证提取到了正确的客户端
90 sockfd_new = accept(sockfd, (struct sockaddr *)&cli_addr, &len);
91 if (sockfd_new < 0)
92 continue;
93 // 6.创建线程
94 pthread_t pth;
95 pthread_create(&pth, NULL, recv_send_fun, (void *)&sockfd_new);
96 pthread_detach(pth);
97 }
98 // 8.关闭套接字
99 close(sockfd);
100 close(sockfd_new);
101 return 0;
102 }