From 7e1109bb84a07bd052584b59f54ab72179ac712a Mon Sep 17 00:00:00 2001 From: flykhan Date: Fri, 8 Sep 2023 09:18:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ctrlc=E7=9A=84=E4=BF=A1?= =?UTF-8?q?=E5=8F=B7=E5=A4=84=E7=90=86=EF=BC=8C=E7=94=A8=E4=BA=8E=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E5=A5=97=E6=8E=A5=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- day2/homework/client | Bin 0 -> 9032 bytes day2/homework/h2.c | 70 ++++++++++++++ day2/homework/h3.c | 46 +++++++++ day2/homework/h4.c | 63 +++++++++++++ day2/homework/h5.c | 46 +++++++++ day2/homework/server | Bin 0 -> 9280 bytes day4/webserver.c | 219 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 444 insertions(+) create mode 100755 day2/homework/client create mode 100644 day2/homework/h2.c create mode 100644 day2/homework/h3.c create mode 100644 day2/homework/h4.c create mode 100644 day2/homework/h5.c create mode 100755 day2/homework/server create mode 100644 day4/webserver.c diff --git a/day2/homework/client b/day2/homework/client new file mode 100755 index 0000000000000000000000000000000000000000..f9ab7a576e717472f52f49da673bc354531ad3fa GIT binary patch literal 9032 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 +#include +#include +#include +#include +#include +#include // toupper + +int main(int argc, char const *argv[]) +{ + int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + { + perror("socket"); + return -1; + } + + struct sockaddr_in addr; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(8000); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) + { + perror("bind"); + } + else + { + printf("bind success\n"); + + struct sockaddr_in src_addr; + char buf[128] = ""; // 接收数据的空间 + socklen_t socklen = sizeof(src_addr); + while (1) + { + bzero(&src_addr, sizeof(src_addr)); + bzero(buf, 128); + + // 接收数据,如果数据未到达,则会阻塞,直到数据到达为止 + ssize_t len = recvfrom(sock_fd, buf, sizeof(buf), 0, (struct sockaddr *)&src_addr, &socklen); + if (len < 0) + { + perror("recvfrom"); + break; + } + + char srcIP[INET_ADDRSTRLEN]; // 16 + int port = ntohs(src_addr.sin_port); // 将网络字节序转化为本地字节序 + inet_ntop(AF_INET, &src_addr.sin_addr.s_addr, srcIP, INET_ADDRSTRLEN); // 将网络数字转换为点分十进制 ip + + printf("从 %s:%d 位置接收到的数据(%lu Bytes): %s\n", srcIP, port, len, buf); + + int i = 0; + while (buf[i]) + { + buf[i] = toupper(buf[i]); // 转大写 + i++; + } + + sendto(sock_fd, buf, len, 0, (struct sockaddr *)&src_addr, socklen); + printf("发送回去的消息为 %s\n", buf); + } + } + + close(sock_fd); + + return 0; +} diff --git a/day2/homework/h3.c b/day2/homework/h3.c new file mode 100644 index 0000000..bc8666e --- /dev/null +++ b/day2/homework/h3.c @@ -0,0 +1,46 @@ +// 编写一个UDP客户端程序, 向服务器发送一个字符串, 并接收服务器返回的字符串并打印出来。 +#include +#include +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + { + perror("socket"); + return -1; + } + + struct sockaddr_in addr; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(8000); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 指定服务器地址 + + // 创建发送的数据 + char buf[128] = "this msg is from client"; + + // 发送 udp 数据 + ssize_t n = sendto(sock_fd, buf, strlen(buf), 0, (struct sockaddr *)&addr, sizeof(addr)); // 将 buf 数据发送给服务器 + if (n > 0) + { + perror("发送成功\n"); + } + + socklen_t addrlen = sizeof(addr); + + ssize_t recvlen = recvfrom(sock_fd, buf, 128, 0, (struct sockaddr *)&addr, &addrlen); // 从服务器获取数据到 buf + if (recvlen < 0) + { + perror("recvfrom"); + return 1; + } + + printf("从服务器获取的数据为 %s\n", buf); + + return 0; +} diff --git a/day2/homework/h4.c b/day2/homework/h4.c new file mode 100644 index 0000000..fd83756 --- /dev/null +++ b/day2/homework/h4.c @@ -0,0 +1,63 @@ +// 编写一个UDP服务器程序, 接收客户端发送的整数, 计算其平方并发送回客户端 +#include +#include +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + { + perror("socket"); + return -1; + } + + struct sockaddr_in addr; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(8000); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) + { + perror("bind"); + } + else + { + printf("bind success\n"); + + struct sockaddr_in src_addr; + int n = 0; // 接收数的空间 + socklen_t socklen = sizeof(src_addr); + while (1) + { + bzero(&src_addr, sizeof(src_addr)); + + // 接收数据,如果数据未到达,则会阻塞,直到数据到达为止 + ssize_t len = recvfrom(sock_fd, &n, sizeof(n), 0, (struct sockaddr *)&src_addr, &socklen); + if (len < 0) + { + perror("recvfrom"); + break; + } + + char srcIP[INET_ADDRSTRLEN]; // 16 + int port = ntohs(src_addr.sin_port); // 将网络字节序转化为本地字节序 + inet_ntop(AF_INET, &src_addr.sin_addr.s_addr, srcIP, INET_ADDRSTRLEN); // 将网络数字转换为点分十进制 ip + + printf("从 %s:%d 位置接收到的数字为(%lu Bytes): %d\n", srcIP, port, len, n); + + int n_to_square = n * n; + + sendto(sock_fd, &n_to_square, len, 0, (struct sockaddr *)&src_addr, socklen); + printf("发送回去的平方值为 %d\n", n_to_square); + } + } + + close(sock_fd); + + return 0; +} diff --git a/day2/homework/h5.c b/day2/homework/h5.c new file mode 100644 index 0000000..8316164 --- /dev/null +++ b/day2/homework/h5.c @@ -0,0 +1,46 @@ +// 编写一个UDP客户端程序, 向服务器发送一个整数, 接收服务器返回的整数并打印出来。 +#include +#include +#include +#include +#include +#include + +int main(int argc, char const *argv[]) +{ + int sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + { + perror("socket"); + return -1; + } + + struct sockaddr_in addr; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(8000); + addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 指定服务器地址 + + // 创建发送的数据 + int n = 5; + + // 发送 udp 数据 + ssize_t sendnum = sendto(sock_fd, &n, sizeof(n), 0, (struct sockaddr *)&addr, sizeof(addr)); // 将 buf 数据发送给服务器 + if (sendnum > 0) + { + perror("发送成功\n"); + } + + socklen_t addrlen = sizeof(addr); + + ssize_t recvlen = recvfrom(sock_fd, &n, 128, 0, (struct sockaddr *)&addr, &addrlen); // 从服务器获取数据到 buf + if (recvlen < 0) + { + perror("recvfrom"); + return 1; + } + + printf("从服务器获取的平方值为 %d\n", n); + + return 0; +} diff --git a/day2/homework/server b/day2/homework/server new file mode 100755 index 0000000000000000000000000000000000000000..71a7d8f39a81df30fa838311d9ac246139bc5f4d GIT binary patch literal 9280 zcmeHNeQaCR6~DHV#%+U>W(CrgQ41OrD#dk5ng!5?oy6@+m6XsXZTAsg9Q(QPn%Kd9 z&YEf+sX{BPEG2B+7O{=7QCL@1kbMY386^E!185ro34}H@71Wlvj4cdSWgXNz=e~RF z_g-uXP1=9Ek>9!Jch5QZ-gD2r@80`zzpr_t)nZ|ktn5pSb9N7hv?pVOH;@El9#+Q| z!*eyefh_{K5Pl@*5jmps!ZcC4Fk=H+0KYn`2Gm(SJVTVKBT6kqiuGlaM`ShnNwLNf zWz5L|)Wf!xIyeiolV^yIigt_%N_xnmUZv2h6naEwM8k+u|FCcPYZLa`tRCQy_aI@7 z{F$XFi>dX38pQm}QqBVP@C?x!4Q511?;g;@c7E1WDg?KR`ttc@PV|qcVA;B!a93^3 zx}IQFPdJj;Q?;kAwyL(q6_2{s^M0d!l-;zYo!3NubOMKMUJgHu0W9BfCa$b__|oy& zN1{Jr#XorK*zw0-MP2$q_A{pnkSxm~y)F-qe#|9bo(K2k!O=!8JE1&yXCAya4}Jh} zC;ZH52LQS1y+04$oCm)#4}MP`9K$nLy$s?afMHO};?clvMP=P;G}6PLan`5AV$m22 zM-)|#sL?*wmr&zOmgA~Fuv-pv@0LUUa1ZN?g(GT+b%i5A*0ooOMOjP<^oL^6UKZ$y z#uXM(@t*4%e>_k`BiRcL9#S-Lkh*C40w<3>2lbYiE6+7@aB&l)E z{{wj(iqvDAzl1yvL28uq?;?+`PYrVZPspRoQ+=F&9eF$Qot%FK`Nhb$a{d(Z7)mJ* z=T9Jyu1>i*|10Ft#VIG}k0Fn)O_g%~XUL;VQ;hRg;6tOp^HlvoQ}VTYrR2NP(D}L6 zwx;PR&r%PQrccf+K{9H$?8VNCVmc%Z+i+FS+kWQZg|bl!gl`DzOhq-+cAd32ga`IOLP~n4P$qPA7fiL;J?r!1BqR;Gfw8 z08OAfQ}m7Ix~(aBxheTZ^Q}1YcIo7& zw%J$z4IVl0f$FUOGsS0f@=|m1awAwsFMnGaI&G0|e?M^v7m%-Zc)#ZD@ZRf{PmgBf z`6F0YxIMAN;QIoTc=>6sFnEtSKYz$s5x=7%=sf?z$a^n5b@9*> z7Y{#k;lc6u9(my6_r@=dJXKlIlW^7#s7n0SJDe54CG5gO52ptAU-;pp7Y;p-QqMei zasSijCrscwDr#|fVvahm!|ioc);pXa2lDj}JMY(VP~Qo5w2?t$|4;cmFazs7 zrg1?z0}l}<8A|W;nMEEhLhtfMn7f!(@F$+PI(crD;O&C06trBF(>agI|9LeXMUgS9 z2TA74*IJLu)86QMF2&%@ z?%_GYTLn+;rur5OdEz1bcz>Ki9;P1W$**&Qzasi4)c@y%&avi-78Q9obe*8L2wE%X zMnSg=8WOZ$(1U`0U(hE7eMZo;g1#x}MM2H&*woN)hqJQ1D-lr>&JC^_m%FMq!MW;h zRoA-QHLmLQw`v8>_3r9gcdh$&vkfzEgD9@Eddx6C3$*3LZA{IH7i8j7Z_EbKI+0U; z5u^Au$``R*<8EViM)6{lU(6`(jQEmFd>ZkkjOM8kFJ^OM{u=RX*j$eBurb(1n$`u> zv#}CJ^WJEul(mZWz=$u)+-n%|GG;IK=pmlBvCn1J5q+TzW+|;7M*Lca+dy-&vFqR- zCl`Kw=G>;&u`!svVtp{;E7)jGd?mwetvT5kt$x`Ooc9In!*mwWa=5Nq*uwVXdTIs# zyG{N_%ZT@xaF@W%>o~r1EiBtkT7R~2e4#)03Oh3<`vk2kzns;|14wh*BDG;ig0mt#e<1HqIKND4w=>r_)&ExV-A&=*2OnlD^bbp?D59h(3%!8lEgZ}|= zCst@m?*NW|Gq>}DJo0#tT?V@<^LwNSHc~n70Ru5Lt|meuR{*Z#HaBdQo13<^$ubKn zF=bact|~EE?Ums=FQVXuT`(%|>WOywdt|uSi^XMsVh;;Md;5A6RSCMju;KQa+(L3F z90|+*Sj;~lD-ks|z(O&9uObH%y}bjVqT^(cR1KotHN15jw|ZNAvTsWxG*4?QGxgt?jae3>Ts#O0j!R?A9TwRGUd~pc} znG3mYf4rNyf&&q-r%^SgmGmpIcsLp{Ffx?Ilpa4Sh+JQf%3R#3F37reMS)e7J@CX? z1wv6CRW7Al%%kog7$Htm)h3jtLHVx-Kn$w!_l5(|hNz0>0l^S;!8kD&OzmEnuBJul zzhH6y1Fw?Idzbe0^j(q8m1G)a_336{@GJ+*8&9vh*#a3n>yrM2)dL)!i#cIqqQiJz#w_WV zYsG9kP&^BhKAlfmMMH6arcY-7-3x_ymL+{U$6OKmHwk5GKgki@4dr+?CZ5haPNCoy z`sVfvnBo2ut0H|m7qtp~>L=B2?*9Wqzg`%m^F6=82aN6mP#GkP6Hb(|c4#!(qOhgYu-k@LP!D2YSagu4T#%0@2{Es1{*Qfmq zDb{B$N;D0sm-HVu>C-u|QCz^#JqXE*uppNGLg;74Pwb;xh5lehQp=G43H~Kyu>GV@ z-^uCwc?}5)YOWt|<@Ne>{~~1@9AcFGmqyJ{H{g%bbcvE zqmaz*JNii0sz{q+5F9yPoz(D85C08dbzl`GAJfNQD|Zfv8&gAOSFGbtOGYf;X3$He`sCA`I)Q! NokC!hsnA^ie*oWx4Q2oU literal 0 HcmV?d00001 diff --git a/day4/webserver.c b/day4/webserver.c new file mode 100644 index 0000000..7e92e0a --- /dev/null +++ b/day4/webserver.c @@ -0,0 +1,219 @@ +// http网页服务器简单实现 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char root_dir[] = "/home/flykhan/html"; + +char html_hi[] = "HTTP/1.1 200 OK\r\n" + "Server: MyWebServer1.0\r\n" + "Content-Type: text/html; charset=utf-8\r\n" + "Accept-Ranges: bytes\r\n" + "Connection: close\r\n" + "\r\n\r\n" + "

hi

\r\n" + "\r\n"; + +char html_404[] = "HTTP/1.1 404 Not Found\r\n" + "Server: MyWebServer1.0\r\n" + "Content-Type: text/html; charset=utf-8\r\n" + "Accept-Ranges: bytes\r\n" + "Connection: close\r\n" + "\r\n\r\n" + "

Page Not Found 404

\r\n" + "\r\n"; + +// 正常网页的 HEAD 头 +char html_ok[] = "HTTP/1.1 200 OK\r\n" + "Server: MyWebServer1.0\r\n" + "Content-Type: text/html; charset=utf-8\r\n" + "Accept-Ranges: bytes\r\n" + "Connection: close\r\n" + "\r\n\r\n"; + +// 正常网页的 图片 头 +char image_ok[] = "HTTP/1.1 200 OK\r\n" + "Server: MyWebServer1.0\r\n" + "Content-Type: image/png;\r\n" + "Accept-Ranges: bytes\r\n" + "Connection: keep-alive\r\n" + "Content-Length: %d\r\n" + "\r\n\r\n"; + +int sock_fd; // 全局定义 服务器 socket 套接字 + +// 自定义信号处理函数 +void signalHandler(int signal) +{ + printf("接收到信号 %d, 套接字为: %d\n", signal, sock_fd); + close(sock_fd); + // printf("套接字现在为 %d\n", sock_fd); +} + +// 定义结构体:用于描述连接的客户端信息 +typedef struct client_s +{ + unsigned char ip[INET_ADDRSTRLEN]; // 16 + int fd; +} Client; + +void *client_task(void *arg) +{ + Client *client = (Client *)arg; + + // 读取客户端的请求 + char buf[1024] = ""; // 存请求报文 + int len = recv(client->fd, buf, 1024, 0); // 接收数据 + printf("request data: %s\n", buf); + + // 解析请求(第一行和头属性以及BODY) + char *line1 = strtok(buf, "\r\n"); + printf("%s\n", line1); + + char method_path_[3][100]; + int i = 0; + char *token = strtok(line1, " "); + while (token != NULL) + { + strcpy(method_path_[i], token); + i++; + token = strtok(NULL, " "); + } + printf("path: %s\n", method_path_[1]); // 解析出地址路径 + + // 查找 html 目录中是否存在此文件 + if (strcmp(method_path_[1], "/") == 0) + { + strcpy(method_path_[1], "/index.html"); + } + + // 拼接服务器文件的完整访问路径 + char path[200] = ""; + strcat(path, root_dir); // 拼接根目录路径 + strcat(path, method_path_[1]); // 拼接请求路径 + + printf("filepath: %s\n", path); + int file_fd = open(path, O_RDONLY); + if (file_fd < 0) + { + // 文件不存在 + // 相应 404 + perror("open"); + send(client->fd, html_404, sizeof(html_404), 0); + } + else + { + // 读取文件的数据(验证读取文件的类型:文本文件、图片文件) + + // 向客户端发送 html_ok 头 + if (strstr(method_path_[1], ".png") != NULL || + strstr(method_path_[1], ".jpg") != NULL) + { + // 发图片头 + struct stat st; + stat(path, &st); + char _ok[sizeof(image_ok) + 20] = ""; + sprintf(_ok, image_ok, st.st_size); // 图片头拼接新获取的图片的大小 + send(client->fd, _ok, strlen(_ok), 0); + } + else + { + // 发文本头 + send(client->fd, html_ok, sizeof(html_ok), 0); + } + // 向客户端发送文件的数据(页面文件) + while (1) + { + char file_buf[512] = ""; + ssize_t read_len = read(file_fd, file_buf, 512); + write(client->fd, file_buf, read_len); + // send(client->fd, file_buf, read_len, 0); + + if (read_len < 512) + { + break; + } + } + close(file_fd); + } + + // 相应一个HELLO主页数据(HTML) + // send(client->fd, html_hi, sizeof(html_hi), 0); + + close(client->fd); + printf("%s 关闭连接\n", client->ip); + free(client); // 回收空间 +} + +int main(int argc, char const *argv[]) +{ + // 1. 创建 socket + sock_fd = socket(AF_INET, SOCK_STREAM, 0); + if (sock_fd < 0) + { + perror("socket"); + return 1; + } + + // 2. bind + struct sockaddr_in server_addr; + bzero(&server_addr, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(atoi(argv[1])); + server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + int flag = bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); + if (flag != 0) + { + perror("bind"); + close(sock_fd); + return 1; + } + + // 注册信号处理函数 + signal(SIGINT, signalHandler); // ctrl + c 发送 + + // 3. 创建监听队列 + listen(sock_fd, 100); + + printf("-----WEB 服务器已开启端口号为:%s-----\n", argv[1]); + + // 4. 开始接收客户端的连接(并发接收多个客户端) + while (1) + { + struct sockaddr_in client_addr; + bzero(&client_addr, sizeof(client_addr)); + socklen_t client_addr_len = sizeof(client_addr); + + int client_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &client_addr_len); + + char clinet_ip[INET_ADDRSTRLEN] = ""; + inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, clinet_ip, INET_ADDRSTRLEN); + printf("%s 连接成功\n", clinet_ip); + + // 创建线程实现并发通信 + Client *client = malloc(sizeof(Client)); // 创建堆空间 + strcpy(client->ip, clinet_ip); + client->fd = client_fd; + + pthread_t tid; + pthread_create(&tid, NULL, client_task, client); + pthread_detach(tid); // 分离线程 + // pthread_join(tid,NULL); + } + + // 主进程的范畴 + close(sock_fd); + + return 0; +}