首页 > 其他 > 详细

网络编程

时间:2020-06-14 09:52:00      阅读:74      评论:0      收藏:0      [点我收藏+]

网络编程

B/S与C/S架构

客户端:Client 浏览器:Browser 服务端:Server

B/S架构

  • 优点 :丰富满足客户的个性化要求,安全性很容易保证,响应速度较快

  • 缺点 : 需要开发客户端和服务器两套程序,开发成本维护成本较高,兼容性差,用户群固定

B/S架构

  • 优点:分布性强,客户端几乎无需维护,开发简单,共享性强,维护简单方便
  • 缺点:个性化低,安全性以及响应速度需要花费巨大设计成本

osi五层协议

  • 物理层

    • 物理机:中继器,集线器,双绞线
  • 数据链路层

    • 物理机:网桥,以太网交换机,网卡
    • 以太网协议
    • mac地址:每块网卡出厂时都被烧制上一个世界唯一的mac地址(可识别特定主机)
      • 可实现广播,单播,组播
  • 网络层

    • 物理机:路由器,三层交换机
    • IP协议:规定网络地址的协议
    • 子网掩码:表示子网络特征的一个参数(通过AND运算判断两个IP地址是否在同一地址)
    • ARP协议:广播的方式发送数据包,获取目标主机的mac地址(功能)
  • 传输层

    • 物理机:四层交换机,四层的路由器
    • tcp协议:可靠传输(tcp的三次握手和四次挥手)
    • udp协议:不可靠传输
  • 应用层(同时包含了会话层和表示层)

socket模块

? Socket又称为套接字,它是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,通过这个接口就可以统一、方便的使用tcp/ip协议的功能

TCP和UDP对比

TCP : 可靠的, 面向连接的协议, 传输效率低, 全双工通信(发送缓存&接收缓存), 面向字节流

UDP : 不可靠, 无连接服务, 传输效率高, 无拥塞控制

TCP协议下的socket

技术分享图片

socket服务端

import socket

sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  # tcp协议的serve

sk.bind((‘127.0.0.1‘,800))  # 调用操作系统资源,绑定一个ip和端口
sk.listen(5)   # 监听

conn, addr = phone.accept()  # 等客户端访问并建立连接

while True:  # 循环收发消息
    try:
        res = conn.recv(1024)   # 接收最大为1024字节
        print(res.decode(‘utf-8‘))
        ret = input(‘>>>‘).encode(‘utf-8‘)
        conn.send(ret)   # 直接发送消息, 不需要地址
    
    except ConnectionResetError:
        break

conn.close()   # 关闭服务/连接
sk.close()

client客户端

import socket

sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

sk.connect((‘127.0.0.1‘,8080))  # 客户端/tcp协议的方法,和server端建立连接


while True:  # 循环收发消息
    res = input(‘>>>‘)
    sk.send(res.encode(‘utf-8‘))
    ret = sk.recv(1024)
    print(ret.decode(‘utf-8‘))

sk.close()  # 挂电话

粘包
  • 粘包发生的本质 : tcp协议的传输是流式传输 数据与数据之间没有边界

  • 发生情况:

    1. 接收方没有及时接受缓冲区的包, 造成多个包接受(客户端发送了一段数据, 服务端只收了一小部分,服务端下次再收的时候还是从缓冲区那上次遗留的数据,产生粘包)
    2. 发送端需要等缓冲区满才发送出去,造成粘包(发送时间间隔很短,数据也很小,会合到一起,产生粘包)
  • 解决办法

    • 问题实质:接收端不知道发送端将要传送的字节流的长度
    • 解决粘包问题的本质:设置边界

方法

  1. 发送时
    1. 先发报头长度
    2. 再编码报头内容然后发送
    3. 最后发真实内容
  2. 接收时:
    1. 先手报头长度,用struct取出来
    2. 根据取出的长度收取报头内容,然后解码,反序列化
    3. 从反序列化的结果中取出待取数据的描述信息,然后去取真实的数据内容
import struct
# 将一个数字转换成长度的bytes类型。
ret = struct.pack(‘i‘,183346)
# 通过unpack反解回来
res = struct.unpack(‘i‘,ret)[0]

##################   服务端如下
import struct
import socket

sk = socket.socket()
sk.bind((‘127.0.0.1‘,9001))
sk.listen()

conn,addr = sk.accept()
msg1 = input(‘>>>‘).encode()
msg2 = input(‘>>>‘).encode()
# num = str()  # ‘10001‘
# ret = num.zfill(4)    # ‘0006‘
# conn.send(ret.encode(‘utf-8‘))
blen = struct.pack(‘i‘,len(msg1))
conn.send(blen)
conn.send(msg1)
conn.send(msg2)
conn.close()
sk.close()
验证客户端的合法性
# 生成一个随机字符串
import os
ret = os.urandom(32)  # 生成一个由32个随机组成的字节
print(ret)
# 在进行加密传输,返回一个加密值与本地对照,可使用hashlib
#也可以使用hmac代替,更加简便
import hmac
a = hmc.new(加的字节, os.urandom32)
ret = h.digest()   #加密的字节
print(ret)

udp协议下的socket

技术分享图片

socket服务端

import socket
sk = socket.socket(type=socket.SOCK_DGRAM)   #创建一个服务器的套接字
sk.bind((‘127.0.0.1‘,9000))        #绑定服务器套接字
conn,addr = udp_sk.recvfrom(1024)
sk.sendto(b‘hi‘,addr)                 # 对话(接收与发送)
sk.close()                         # 关闭服务器套接字

socket客户端

import socket
ip_port=(‘127.0.0.1‘,9000)
udp_sk=socket.socket(type=socket.SOCK_DGRAM)
udp_sk.sendto(b‘hello‘,ip_port)
msg,addr=sk.recvfrom(1024)
print(msg.decode(‘utf-8‘),addr)

socketserver模块

  • 基于socket完成的(socket属于底层模块)
  • 可实现并发编程(两个作用)
    • 循环建立链接的部分,每个客户链接都可以连接成功
    • 通讯循环的部分,就是每个客户端链接成功之后,要循环的和客户端进行通信
# 固定格式
import time
import socketserver  # 引入模块

class Myserver(socketserver.BaseRequestHandler):  # 类名自定义,但必须继承
    def handle(self):
        conn = self.request  # 等同于conn管道
        while True: # 编写传输内容
            try:
                content = conn.recv(1024).decode(‘utf-8‘)
                conn.send(content.upper().encode(‘utf-8‘))
                time.sleep(0.5)
            except ConnectionResetError:
                break
server = socketserver.ThreadingTCPServer((‘127.0.0.1‘,9001),Myserver)
server.serve_forever()

网络编程

原文:https://www.cnblogs.com/tonxin66/p/13123724.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!