[C语言][网络编程][源码阅读]简单Web服务端实现:浏览器访
目录
零、完整源码下载
一、代码运行结果(这个代码有啥用?)
二、服务器端(Server)与 客户端(Client)
三、用套接字来连接网络
四、源码阅读
1、webserv_linux.c是基于多线程模型实现的Web服务器端
2、Socket 套接字部分
(1) 套接字 serv_sock 的作用
(2) Request Header ,实现响应GET请求
(3) 套接字 clnt_sock的作用
(4) Response Header ,响应消息
(5) 调用自定义函数 send_data() 响应客户端请求
(6) index.html 源码
零、完整源码下载
图灵社区《TCP/IP网络编程》
https://www.ituring.com.cn/book/1284
(1) 右侧 随书下载
TCPIP_Src.zip
(2) 下载 解压 完整源码位于TCPIP_Src.zip\Chapter24 source
(3) 含有文件index.html
、webserv_linux.c
、webserv_win.c
一、代码运行结果(这个代码有啥用?)
C/S 请求响应 全流程示意图1、启动服务器端 自定义端口号为 9190
自定义端口 9190
2、打开火狐浏览器,输入 http://127.0.0.1:9190/index.html
并回车
浏览器访问
- 自定义服务器端口号为
9190
$ ls
index.html webserv_linux.c
$ gcc webserv_linux.c -o wserv -lpthread
$ ./wserv 9190
Connection Request : 127.0.0.1:45472
Connection Request : 127.0.0.1:45474
Connection Request : 127.0.0.1:45476
Connection Request : 127.0.0.1:45478
. . .
- 在浏览器地址栏中输入
http://127.0.0.1:9190/index.html
,该请求相当于连接到IP地址为127.0.0.1
(可以用localhost
代替)、端口号为9190
的套接字,并请求index.html
文件
二、服务器端(Server)与 客户端(Client)
-
服务器端(Server):由
webserv_linux.c
编译后生成可执行文件wserv
,运行./wserv 9190
开始监听端口9190
-
客户端(Client) :这里是浏览器,浏览器内部会创建
套接字
,浏览器会可视化HTML
格式的文件
三、用套接字来连接网络
服务端套接字
服务端套接字 猪仔图标🐖是我个人喜好,和编程无关书上
[1]
用了 安装电话机socket()
、分配电话号码bind()
、连接电话线listen()
、拿起话筒accept()
、通话read()/write()
、挂断close()
这个例子来说明服务端套接字一系列函数的使用顺序和场景,贴切、实用、好记👍
客户端套接字
客户端套接字 独角兽图标🦄是我个人喜好,和编程无关本文中浏览器承担了客户端的角色,这里不需要自己写客户端的代码了
四、源码阅读
1、webserv_linux.c
是基于多线程模型实现的Web服务器端
-
客户端(浏览器)每次请求时,服务器端都会创建1个新线程响应客户端请求
多线程模型服务端
2、Socket 套接字部分
- 命令行参数,argv[0] 是可执行程序名
wserv
,argv[1]是我们自定义的端口号9190
- 服务端依次执行:创建套接字
socket()
、分配IP地址和端口号bind()
、进入等待连接请求状态listen()
、允许连接accept()
、数据交换read()/write()
、断开连接close()
(1) 套接字 serv_sock
的作用
服务端套接字serv_sock的作用
-
INADDR_ANY
可以自动获得服务器端的计算机IP地址,本文中服务端和客户端都是本机地址127.0.0.1 - 服务器端与客户端建立连接后,首先在服务器端的命令行窗口显示一条连接信息
Connection Request : 127.0.0.1:客户端端口号
,然后会创建1个新线程响应客户端请求
(2) Request Header
,实现响应GET
请求
GET /index.html HTTP/1.0
Host: localhost:9190
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
请求消息
Request Header
- 这些
Request Header
的内容由火狐浏览器自己填充,发送给服务端
(3) 套接字 clnt_sock
的作用
套接字 clnt_sock的作用
(4) Response Header
,响应消息
HTTP/1.0 200 OK
Server: Linux Web Server
Content-length: 2048
Content-type: text/html
响应消息
Response Header
- 在浏览器这里看到的
Repsonse Header
数据是服务器端响应请求返回的,并且浏览器会可视化服务器端响应回来的index.html文件(text/html类型)
(5) 调用自定义函数 send_data()
响应客户端请求
自定义函数 send_data() 响应客户端请求
(6) index.html
源码
<html>
<head>
<title>NETWORK</title>
</head>
<body>
<font size=5>
TCP/IP Socket Programming
Hello World!
</font>
</body>
</html>
我的小结
- 1、【Web服务器端】是以【HTTP协议】为基础【传输超文本】的【服务器端】
- 2、浏览器属于套接字的【客户端】,浏览器内部会创建【套接字】,浏览器还会将服务器端传输的HTML格式的超文本解析为可读性较强的视图
- 3、网络编程本质就是Socket编程,socket、bind、listen、accept、close,当然还有半关闭的shutdown这些,服务端与客户端的连接建立之后,更多还是对系统编程的要求,如各种IO函数(操作文件),线程的创建、销毁,很认同作者强调的提高系统编程能力的必要性
参考资料
-
[1] 《TCP/IP网络编程》(尹圣雨)ISBN: 9787115210548
https://www.ituring.com.cn/book/1284
个人推荐:强烈推荐⭐!绝赞好书♥!清晰易懂🉑!代码可运行🈶! -
[2]
int fflush(FILE *stream)
https://www.runoob.com/cprogramming/c-function-fflush.html -
[3]
char *fgets(char *str, int n, FILE *stream)
https://www.runoob.com/cprogramming/c-function-fgets.html -
[4]
int fputs(const char *str, FILE *stream)
https://www.runoob.com/cprogramming/c-function-fputs.html -
[5]
char *strtok(char *str, const char *delim)
https://www.runoob.com/cprogramming/c-function-strtok.html -
[6]
char *strstr(const char *haystack, const char *needle)
https://www.runoob.com/cprogramming/c-function-strstr.html