python socket
b站 奇乐编程学院 TCP/IP网络通信之Socket编程入门
单线程socket,socket入门代码
下面是一个socket例子,实现的是服务器接收到来自客户端的数据,又原封不动发送给客户端的功能。
服务器端:
服务器端绑定bind的ip地址可以是任意的,表示服务器端监听任意ip地址,也就是可以接收任意客户端的信息。
只有在客户端连接的端口号是bind里设置的端口号时,才会和服务器端连接上。
1 | # 下面是一个socket例子,实现的是服务器接收到来自客户端的数据,又原封不动发送给客户端的功能。 |
保存的该python文件,比如为server.py,然后在终端执行 python server.py
,就启动了服务器端socket。
在新打开一个终端,输入 nc 127.0.0.1 1234
(127.0.0.1 是一个回送地址(lookback address),代表本地计算机,1234是端口号)。
按下回车,就可以看见服务器端收到了一个新连接,显示('127.0.0.1', 53046) connected
,表示接收到ip为127.0.0.1的客户端,客户端端口为53046.
然后在客户端窗口中随便输入字符串,服务器也会原封不动的发送回来。

客户端:
1 | import socket |
结果为:
多线程的socket服务器
服务器并发的与多个客户端进行通信
1. 通过创建线程来响应不同客户端的请求
服务器端:
1 |
|
结果:

多线程局限性:由于python的 GIL(https://python.land/python-concurrency/the-python-gil) 的存在,python中的线程其实做不到真正的并发,并且线程自身也会占用额外的系统资源(线程内存开销、线程切换开销)
除了线程之外,还可以使用基于事件驱动的selectors来实现多个连接的并发,或者通过更高层的asyncio来实现异步的socket代码。
简易HTTP服务器
HTTP是TCP协议的一个典型应用,也是浏览器与服务器交互的主要方式。通常服务器会监听80端口,然后等待客户端的连接(也就是浏览器比如搜索一个网址,是向服务器发起一次请求)。
客户端在连上服务器以后,首先需要指定要访问的资源,然后客户端会提供一系列额外的信息,这些信息每一条都是以冒号分隔的键/值对,信息是比如浏览器版本等,这些额外信息称作消息的头部(header)。随后是一个空行,再之后是消息的主体(body)(如果有的话)。
服务器在收到消息后,会以同样格式来响应客户端的请求,首先第一行是一个状态行(status line),里面包含一个状态码,比如200代表请求成功,404代表请求的资源不存在。接着同样是一系列键/值对,里面包含了请求资源的类型,服务器信息等。再后面是一个空行,再之后是消息的主体(body)(如果有的话)。

http socket的例子
1 | import socket |
在该python文件(比如socket_http.py)当前路径下,有一个子文件夹,取名叫webroot,里面有一些网页,代表客户端搜索不同的网址,会连接到服务器的哪些个网页里(这里服务器的路径指的就是该python文件)。

然后启动 sudo python3 socket_http.py
,在浏览器页面中输入 http://127.0.0.1/
根路径,代码里要返回index.html这个文件,这个在网页中一般表示主页的意思,里面的内容也是自己定义的,这里”/“就是指的根目录。如果在浏览器中输入 http://127.0.0.1/123.HTML
,服务器端会返回给浏览器(客户端)123.html这个文件。
在浏览器(客户端)和服务器建立请求时,不用特定指定端口了,80就是服务器默认端口了,浏览器要建立就直接是80端口了。(每次发送连接请求,客户端的端口各不相同)
index.html内容:
1 | <html> |
浏览器呈现:
123.html内容:
1 | <html> |
浏览器呈现:
如果输入一个没有的链接:
这样就实现了一个浏览器http和服务器的socket通信。
python的标准库里已经实现了一个简易的HTTP服务器,它主要被用在开发和测试中,调用起来很方便,命令是:python -m http.server 8000