python - 网络编程

2021-07-11 15:05

阅读:651

标签:交换机   ima   RoCE   ret   bsp   close   链接   content   div   

★定义

由于不同机器上的程序要通信,才产生了网络

技术分享图片

◇C/S架构

server服务端

client客户端

◇B/S架构

 broswer浏览端

server客户端

  如:各种小程序和公众号

★通信

◇网线

连接每一台机器的桥梁

◇网卡

每台计算机有全球唯一的mac地址(物理地址)

◇ARP协议

通过IP地址找到对应的MAC地址

◇交换机

多台机器之间通信的问题

◇网关

局域网中的机器想要访问局域网外的机器,需要网关

◇网段

IP地址和子网掩码按位【与运算】

◇IP协议

  • 127.0.0.1 本地回环地址
  • 为每一台计算机分配IP地址
  • 确定哪些地址在同一个子网络

◇通信协议

TCP协议

  全双工,双方都可以收发信息

 

  建立通信的过程

  1,建立连接:三次握手

  2,数据传输:长链接

  3,断开连接:四次挥手

UDP协议

是一个简单的传输协议,只把数据发出去,但不能保证它们能到达目的地

◇端口

在计算机上,每一个网络通信的程序,都会开一个端口

端口范围:0-65535

一般情况下我们用:8000之后的端口

◆IP和端口的区别

IP:确定唯一的一台机器

端口:确定唯一的一个程序

★五层模型

◇应用层

  协议:

  • HTTP协议
  • HTTPS协议
    • 花钱,可靠
  • FTP传输协议
  • SMTP协议

◇传输层

选择通信协议

  • TCP
  • UDP

◇网络层

给上一层的信息加上IP信息

  IP协议

◇数据链路层

给上一层的信息加上MAC地址

  ARP协议

◇物理层

  网线网卡

    传输比特流0101010

★socket模块

只要确定了IP和Port,就能使用socket来与之通信

 

◇类型

  • 基于文件类型:AF_UNIX
  • 基于网络类型:AF_INEF

 

◇socket实例

基于TCP方式(会黏包)

技术分享图片技术分享图片
 1 import socket
 2 
 3 sk = socket.socket()    # 实例socket对象
 4 sk.bind((127.0.0.1, 8080))    # 绑定ip和端口
 5 sk.listen()             # 监听
 6 
 7 conn, addr = sk.accept()    # 建立连接
 8 conn.send(bhello)         # 发送消息
 9 res = conn.recv(1024).decode(utf-8)   # 接收消息
10 print(res)
11 conn.close()        # 关闭连接
12 
13 sk.close()      # 关闭socket对象
server.py
技术分享图片技术分享图片
1 import socket
2 
3 sk = socket.socket()    # 创建socket对象
4 sk.connect((127.0.0.1, 8080))     # 创建连接
5 
6 res = sk.recv(1024).decode(utf-8)     # 接收信息
7 print(res)
8 sk.send(bok)      # 发送信息
9 sk.close()      # 关闭连接
client.py

 

基于UDP方式(会丢包)

技术分享图片技术分享图片
 1 import socket
 2 
 3 sk = socket.socket(type=socket.SOCK_DGRAM)  # 创建一个基于UDP协议的socket对象
 4 sk.bind((127.0.0.1, 8080))     # 绑定IP和port
 5 
 6 ret, addr = sk.recvfrom(1024)   # 接收消息 并接收一个 addr
 7 print(ret.decode(utf-8))
 8 sk.sendto(bhello,addr)        # 发送消息 需要传addr
 9 
10 sk.close()      # 关闭socket对象
server.py
技术分享图片技术分享图片
 1 import socket
 2 
 3 sk = socket.socket(type=socket.SOCK_DGRAM)  # 创建一个基于UDP协议的socket对象
 4 addr = (127.0.0.1, 8080)
 5 
 6 sk.sendto(bhi, addr)
 7 ret,addr = sk.recvfrom(1024)        # 接收消息 并接收一个 addr
 8 print(ret.decode(utf-8))          # 发送消息 需要传addr
 9 
10 sk.close()      # 关闭socket对象
client.py

 

◇黏包(只在TCP协议中)

原因:面向连接的流传输,数据是无边界的

  1,缓冲机制:不知道客户端发送的数据的长度,recv接收不完的数据,会缓存在内存里,等待下一个recv

  2,优化算法:连续的小数据包会被合并在一起发送,会被一个recv接收

解决办法

发送大的数据前,告诉接收端我要传多大的数据,接收端接收合适的数据大小

 

通过struct模块

  固定长度的bytes

  pack:就是即将把一个数据转换成固定长度的bytes类型

  unpack:unpack之后拿到的数据是一个元祖

技术分享图片技术分享图片
 1 import socket
 2 import struct
 3 
 4 sk = socket.socket()
 5 sk.bind((127.0.0.1, 8090))
 6 sk.listen()
 7 
 8 conn, addr = sk.accept()
 9 while True:
10     cmd = input(>>>)
11     if cmd == q:
12         break
13     conn.send(cmd.encode(gbk))       # 发命令
14     num = conn.recv(4)
15     num = struct.unpack(i, num)[0]    # unpack之后拿到的数据是一个元祖
16     ret = conn.recv(num).decode(gbk)      # 接收信息
17     print(ret)
18 
19 
20 conn.close()
21 sk.close()
server.py
技术分享图片技术分享图片
 1 import socket
 2 import subprocess
 3 import struct
 4 
 5 sk = socket.socket()
 6 sk.connect((127.0.0.1, 8090))
 7 
 8 while True:
 9     cmd = sk.recv(1024).decode(gbk)   # 接收一个命令
10     if cmd == q:
11         break
12     res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # 在本地执行命令
13     stdout_ret = res.stdout.read()  # gbk字节
14     stderr_ret = res.stderr.read()  # gbk字节
15     num = len(stdout_ret) + len(stderr_ret)
16     sk.send(struct.pack(i, num))      # 把数据包的大小传过去(这个数据包本身4字节)
17     sk.send(stdout_ret)     # 将命令结果发给服务端
18     sk.send(stderr_ret)     # 将命令结果发给服务端
19 
20 sk.close()
client.py

 

python - 网络编程

标签:交换机   ima   RoCE   ret   bsp   close   链接   content   div   

原文地址:https://www.cnblogs.com/sunch/p/9551250.html


评论


亲,登录后才可以留言!