• 网络编程总结


    网络编程小结

    网络架构及演变过程

    单机架构

    不需要联网

    CS架构

    客户端和服务端直接交互

    BS架构

    客户端嫁接在浏览器上。浏览器与服务端交互

    互联网和互联网的组成

    教材版

    1. 边缘部分:服务器和客户端

    2. 核心部分:路由器/基站

    科普版

    1. 硬件:网工的事情

    2. 软件:一大堆协议

    OSI七层协议

    物理层

    硬件:传输电信号

    数据链路层

    对电信号分组

    以太网头:

    head:

    发送地址(mac地址):

    接受地址(mac地址):

    数据类型:

    data

    mac地址可以确定唯一计算机

    网络层

    对电信号分组

    head

    以太网头:

    发送地址(ip地址):

    接受地址(ip地址):

    data

    互联网就是多个局域网,局域网通过路由器连接

    ip地址+mac地址就会找到全世界独一无二的计算机

    传输层

    找到一个应用程序,每一个应用程序都会有一个独一无二的端口

    ip地址+mac地址+端口找到全世界独一无二的计算机唯一的应用程序

    应用层

    数据交互

    Socket抽象层

    应用层和传输层之间,你就是写了一个应用程序,客户端和服务端就是一个应用程序

    TCP协议的三次握手和四次挥手

    三次握手建立连接

    1. 客户端像服务端发出连接的带上SYN的请求给服务端

    2. 服务端收到后,返回一个带上SYN和ACK的请求给客户端

    3. 客户端进入连接状态后,并且发送一个带上ACK的请求给服务端

    4. 服务端收到进入连接状态

    四次挥手断开连接

    1. 客户端发出带有FIN的请求给服务端

    2. 服务端返回一个带有ACK的请求给客户端,说他已经知道了

    然后客户端可能会有遗留的数据返回给客户端,会在这个时候发完

    1. 服务端发完之后才会发送一个带有FIN和ACK的请求给客户端

    如果客户端没有收到这条请求,就没有第四条请求给服务端,服务端会隔一段时间再发一次带有FIN和ACK的请求给客户端,如果在2MSL时间内,客户端一直没有响应,则强行关闭

    1. 客户端返回一个带有ACK的请求给服务端,连接正常关闭

    基于TCP协议的Socket套接字编程

    服务端

    import socket

    # 1. 符合TCP协议的手机
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #TCP

    # 2. 绑定手机号 110
    server.bind(('127.0.0.1',8000)) # 127.0.0.1代表本地

    server.listen(5)  #半连接池

    # 3. 等待客户端连接
    print('start....')
    # 链接循环


    while True:
       # 通信循环
       conn,client_addr = server.accept()
       while True:
           try:
               # 4.收到消息receive
               data = conn.recv(1024)
               print(data)
               
               # 5.回消息
               conn.send(data.upper())
           except connectionAbortedError:
               continue
           except connectionResetError:
               break

     

     

    客户端

    import socket

    # 1. 创建符合TCP协议的手机
    client = socket.socket(socket.AF_INET,socket.sock_STREAM)

    # 2. 拨号
    client.connect(('127.0.0.1',8000))


    while True:
       msg = input('please enter your msg') # dir
       # 3. 发送消息
       client.send(msg.encode('utf8'))
       
       # 4. 接收消息
       data = client.recv(1024)
       print(data)
       

    模拟ssh远程执行命令

    在客户端处模拟ssh发送指令,服务端通过subprocess执行该命令,然后返回命令结果

    服务端

    import socket
    import subprocess

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

    server.bind(('192.168.11.210',8000))
    server.listen(5)

    print('start...')
    while True:
       conn,client_addr = server.accept()
       print(client_addr)
       
       while True:
           try:
               cmd = conn.recv(1024) #dir
               print(cmd)
               
               # 帮你执行cmd命令,然后把执行结果保存到管道里
               pipeline = subprocess.Popen(cmd.decode('utf8'),
                                          shell=True,
                                          stderr=subprocess.PIPE,
                                          stdout=subprocess.PIPE)
               stderr = pipeline.stderr.read()
               stdout = pipeline.stdout.read()
               
               conn.send(stderr)
               conn.send(stdout)
               
           except ConnectionResetError:
               break
               

    客户端

    import socket

    # 1. 创建符合TCP协议的手机
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    # 2. 拨号
    client.connect(('192.168.11.210',8000))

    while True:
       msg = input('please enter your msg') # dir
       # 3.发送消息
       client.send(msg.encode('utf8'))
       
       # 4. 接收消息
       data = client.recv(10)
       print(data.decode('gbk'))

    粘包问题

    1. 两个数据非常小,然后间隔时间又短

    2. 数据太大,一次取不完,下一次还会取这个大数据

    解决粘包问题

    • 在传数据之前,传一个数据的大小,数据的大小必须得定长

    基于UDP协议的socket套接字编程

    • UDP无连接

    服务端

    import socket

    server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    server.bind(('127.0.0.1',8000))

    print('start...')
    while True:
       data,client_addr = server.recvfrom(1024)
       print(client_addr)
       print(data)
       server.sendto(data.upper(),client_addr)
       
       

    客户端

    import socket

    client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

    while True:
       msg = input('please enter your msg')
       client.sendto(msg.encode('utf8'),('127.0.0.1',8000))
       
       data = client.recvfrom(1024)
       print(data)
       
       

    基于socketserver实现并发的socket套接字编程

    • 让服务端同事与多个客户进行连接,以前我们写的是一个警局有5个电话只有1个人,现在写的是5部电话5个人

    服务端

    # 同一时刻有多个人在接听
    import socketserver
    import subprocess
    import struct

    class MyHandler(socketserver.BaseRequestHandler):
       # 通信循环
       def handle(self):
           
           while True:
               try:
                   cmd = self.request.recv(1024)
                   print(cmd)
                   
                   pipeline = subprocess.Popen(cmd.decode('utf8')
                                              shell=True:
                                              stderr=subprocess.PIPE,
                                              srdout=subprocess.PIPE)
                   stdout = pipeline.stdout.read()
                   stderr = pipeline.stderr.read()
                   
                   count_len = len(stdout) + len(stderr)
                   guding_bytes = struct.pack('i',count_len)
                   
                   self.request.send(guding_bytes) # 4
                   
                   self.request.send(stderr + stdout)
                   
               except ConnectionRestError:
                   break
                   
                   
    # 使用socketserver的连接循环(并发),但是使用了自己的循环通信
    # myhandler = MyHandler()

    if __name__ == '__main__':
       server = socketserver.ThreadingTCPServer(('127.0.0.1',8000),MyHandler,bind_and_sctive=True)
       print('start...')
       server.serve_forever()
                                                 

     

  • 相关阅读:
    Redis(五)——主从做读写分离原理与优化
    Redis(四)——持久化方案(RDB和AOF使用)
    Redis(三)——高级用法(GEO地理位置信息)
    Redis(二)——五大数据类型的基本操作(字符串类型,哈希类型,列表类型,集合类型,有序集合类型)
    Redis(一)——redis初识,redis安装和启动
    15 Ajax技术
    ORM多表分组、F与Q查询
    ORM多表操作
    ORM单表操作
    CentOS 7 下 rdesktop 的安装
  • 原文地址:https://www.cnblogs.com/zrx19960128/p/11099007.html
Copyright © 2020-2023  润新知