python 网络编程

osi 七层协议
应用层
表示层
会话层
上三层可以归并为一层应用层(socket)
传输层 TCP UDP
网络层(ip层 加ip包头)
数据链路层(加mac地址源目标地址)
物理层(底层0110)

首先我们通过socket来实现我们的简单的客户端与服务端的简单代码
服务端代码接收并返回大写字母回去

import socket
#AF_INET ipv4地址族 SOCK_STREAM 是一个流式协议,属于tcp,所以存在粘包现象后面说
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',8080))
server.listen(5)
while True:
conn,client_addr = server.accept()
try:
while True:
res = conn.recv(1024)
if len(res) == 0: break
conn.send(res.upper())
except:
conn.close()

  

客户端:

import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))

while True:
client.send(b'hello world')
data = client.recv(1024)
print(data.decode('utf-8'))
View Code

但是以上的客户端我们只能实现对单用户服务再来用户我们就不能接客了哈哈,所以我们需要对代码进行改进这边我们使用的socketserver来实现,在此之后会用多线程的方式实现。

```python
服务端代码
import socketserver
class MyHandle(socketserver.BaseRequestHandler):
def handle(self):
print(self.request)#相当于是conn 就是从半连接池中拿取的socket的连接处理的对象
while True:
try:
data = self.request.recv(1024)
self.request.send(data)
print(data)
except:
self.request.close()

phone = socketserver.ThreadingTCPServer(("127.0.0.1",8080),MyHandle)
phone.serve_forever()#一直服务
View Code
客户端代码
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))

while True:
msg = input("please input")
client.send(msg.encode('utf-8'))
data = client.recv(1024)
print(data.decode('utf-8'))
```
View Code


解释下上面的场景为啥不会卡住,因为相当于是来一个请求,有消息,我们的accept会从半连接池中取出连接句柄,开启一个线程来执行我们的recv等操作,所以不会卡住,而如果不用线程则会陷入拿了句柄只能等这个处理结束了,才能再去拿句柄。

```python
#服务端代码如下:
import socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',8080))
server.listen(5)
import threading
def Talk(conn):
while True:
try:
res = conn.recv(1024)
print(res)
if len(res) == 0: break
res = res.decode("utf-8")
conn.send(res.upper().encode("utf-8"))
except:
conn.close()
while True:
conn,address = server.accept()
t = threading.Thread(target=Talk,args=(conn,))
t.start()
#客户端如下:
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))

while True:
msg = input("please input")
client.send(msg.encode('utf-8'))
data = client.recv(1024)
print(data.decode('utf-8'))
```
View Code

补充
192.168.11.16/27
主机的个数为32-27=5 2^5=32 32 -2 =30主机数为30
主机范围是0-31-63-95 必须是32的倍数,16在0-32之间 31是广播地址 网络号是192.168.11.0
接下来会引入select敬请期待

原文地址:https://blog.csdn.net/wuyong15221125927/article/details/110824300    我的csdn博客

原文地址:https://www.cnblogs.com/wuyongmax/p/14098922.html