zoukankan      html  css  js  c++  java
  • 网络编程

    [doc]

    一、网络编程大体图

    二、TCP协议

    TCP协议又叫:流失协议、可靠协议

    1.TCP协议像流水一样一直发送,一直接收

    2.TCP协议可靠的原因:有反馈机制(发送一句,回复一句才会发送下一句)

    洪水攻击:同一时间发送给服务器大量请求

    1.三次握手,四次挥手图

    2.tcp代码

    1.简单版

    服务端:

    import socket
    
    server = socket.socket()  # 生成对象
    server.bind(('127.0.0.1', 8080))  # 绑定IP和端口 (自己的)
    server.listen(5)  # 半连接池,允许等待数
    
    conn, addr = server.accept()  # 等待接听
    # conn:地址 addr:端口号(随机分配)
    
    while True:
        data = conn.recv(1024)  # 接收
        print(data)  # 打印接收的内容
        # 判断如果接收的是空,就跳出循环
        if len(data) == 0:
            break
        conn.send(data.lower())  # 发送反馈内容
    
    

    客户端:

    import socket
    
    client = socket.socket()  # 生成对象
    client.connect(('127.0.0.1', 8080))  # 拨号,对方IP和端口
    
    while True:
        msg = input('请输出 >>>:').strip().encode('utf-8')  # 转二进制
        if len(msg) == 0:
            continue
        client.send(msg)  # 发送
        data = client.recv(1024)  # 接收反馈内容
        print(data)
    
    

    2.电影上传

    1.打包,固定长度模块struct

    注意:一般用'i'模式,固定4个字节 长度,q模式最大8个字节长度

    import struct
    """
    利用struct给
    """
    res1 = 'asdfkjhksdhfksadhfkkshfasjdfklasddfjkl'
    print('开始的', len(res1))
    res2 = struct.pack('i', len(res1))
    print('压缩的', len(res2))
    
    res3 = struct.unpack('i', res2)[0]
    print('解压的', res3)
    
    

    客户端:

    import os
    import socket
    import struct
    import json
    
    move = socket.socket()  # 生成对象
    move.connect(('127.0.0.1', 8080))  # 写服务端的IP,port
    
    while True:
        # 1.拼接文件路径
        MOVE_PATH = r'E:学习视频python老男孩对象day20视频'
        move_list = os.listdir(MOVE_PATH)
    
        # 循环打印
        for i in move_list:
            print(move_list.index(i)+1, i)
        # 用户选择
        choice = input('请选择你要上传的电影>>>:')
        # 判断输入是否为数字
        if choice.isdigit():
            # 转成int型
            choice = int(choice)-1
            # 判断是否在范围内
            if choice in range(0, len(move_list)):
                # 拿到用户选择的文件
                move_choice = move_list[choice]
                # 拼接文件路径
                move_path = os.path.join(MOVE_PATH, move_choice)
                # 拿到文件大小
                move_size = os.path.getsize(move_path)
                # 定义字典容器,数据放到字典中
                move_dict = {'name': '陪你到老.mp4', 'size': move_size}
                # 转成json格式和转成二进制格式的字典
                json_dict = json.dumps(move_dict).encode('utf-8')
                # 制作字典报头
                hander_dict = struct.pack('i', len(json_dict))
    
                # 发送报头
                move.send(hander_dict)
                # 发送字典
                move.send(json_dict)
    
                # 发送文件
                with open(move_path, 'rb')as f:
                    for i in f:
                        move.send(i)
            else:
                print('你选的不在范围内')
        else:
            print('请输入数字')
    
    

    服务端:

    import os
    import socket
    import json
    import struct
    
    server = socket.socket()  # 生成对象
    server.bind(('127.0.0.1', 8080))  # 绑定IP,port
    server.listen(5)  # 半连接池
    
    while True:
        data, addr = server.accept()  # 接受连接
        # print(data, addr)
        while True:
            try:
                # 接收字典报头
                dict_hand = data.recv(4)
                # 解析字典报头,拿到字典长度
                dict_len = struct.unpack('i', dict_hand)[0]
                # 接收字典长度,就是接收字典
                dict_json = data.recv(dict_len)
                # 解开json,解码二进制
                dict = json.loads(dict_json.decode('utf-8'))
                # 从字典中获取文件的大小长度
                move_size = dict.get('size')
                # 循环接收,并写入文件
                accept_size = 0
                # print(dict.get('name'))
    
                with open(dict.get('name'), 'wb')as f:
                    while accept_size < move_size:
                        accept = data.recv(1024)
                        f.write(accept)  # 写入文件
                        accept_size += len(accept)
                    print('上传成功')
            except ConnectionResetError as f:
                print(f)
                break
        data.close()
    
    

    3.json补充,序列化类

    from datetime import *
    import json
    
    """序列化类.先转换成字符串型,才能序列化"""
    
    # 1.手动转化成字符串型
    b = str(datetime.today())
    c = str(date.today())
    a = {'1':b,'2':c}
    # print(json.dumps(a))
    d = str(datetime.today().strftime('%Y-%m-%d'))
    # print(d)
    e = type(datetime.today())
    print(e)
    
    
    
    # 2.定义一个继承json的新的类
    class MyJson(json.JSONEncoder):
        def default(self, o):
            if isinstance(o,datetime):
                return o.strftime('%Y-%m-%d %X')
            elif isinstance(o,date):
                return o.strftime('%Y-%m-%d')
            else:
                return super().default(self,o)
    res = json.dumps(a)
    print(res)
    

    4.subprocess补充

    import subprocess
    
    
    cmd = input('输入命令>>>:')
    obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    print(obj.stdout.read().decode('gbk'))  # 正确命令返回结果
    print(obj.stderr.read().decode('gbk'))  # 错误命令返回结果
    
    
    #  subprocess获取到的数据  拿完就没有了  不能重复拿
    
    

    三、UDP的使用

    1.简介

    udp协议又叫:

    ​ 1.数据报协议(自带报头)

    ​ 2.没有双向通道

    ​ 3.也没有半连接池

    发送数据就类似发短信,给指定的IP,port发送,不用管对方有没有收到

    ​ 缺点:容易数据丢失,不安全

    ​ 优点:速度快

    2.使用基本代码

    服务端:

    import socket
    
    server = socket.socket(type=socket.SOCK_DGRAM)  # UDP协议
    server.bind(('127.0.0.1', 8080))   # 绑定自己的地址端口
    
    
    while True:
        data, addr = server.recvfrom(1024)  # 接收
        print('接收到数据:', data)
        print('地址:', addr)
        server.sendto(data.upper(), addr)   # 发送
    
    

    客户端:

    import socket
    
    client = socket.socket(type=socket.SOCK_DGRAM)
    
    server = ('127.0.0.1', 8080)  # 要发送的地址端口
    while True:
        client.sendto(b'hello', server)  # 发送
        data, addr = client.recvfrom(1024)   # 接收
        print(data)  # 打印
    
    

    2.1简易版qq

    服务端:

    import socket
    
    phone = socket.socket(type=socket.SOCK_DGRAM)  # 1.建立对象
    addres = ('127.0.0.1', 8080)
    
    while True:
        send = input('请输入要发送的内容>>>:').encode('utf-8')
        phone.sendto(send, addres)  # 2.发送内容,填写地址
        data, addr = phone.recvfrom(1024)  # 3.接收
        print('收到内容:', data.decode('utf-8'))  # 4.接收转码
    
    
    

    客户端:

    import socket
    
    server = socket.socket(type=socket.SOCK_DGRAM)  # 1.建立对象
    server.bind(('127.0.0.1', 8080))  # 2.绑定地址
    
    while True:
        data, addr = server.recvfrom(1024)  # 3.接收
        print('收到的内容:', data.decode('utf-8'))  # 4.打印,解码
        print('对方地址:', addr)  # 打印,解码
        msg = input('请输入你要回复的内容>>>:').encode('utf-8')
        server.sendto(msg, addr)  # 5.回复发送
    
    

    四、UDP和TCP的区别

    UDP:类似发短信(只管往某个电话发短信,不管对方有没有看)

    ​ 1.允许发空(自带报头)

    ​ 2.不会粘包(自带报头)

    ​ 3.UDP支持并发

    ​ 4.UDP服务协议不安全(没有三次握手)

    ​ 5.UDP速度更快

    TCP:类似打电话(有人接听,有人回复)

    ​ 1.不允许发空(没有报头)

    ​ 2.会粘包(没有报头)

    ​ 3.安全系数高(有三次握手)

  • 相关阅读:
    向代码致敬,寻找你的第83行
    佛系程序员的月薪五万指南
    再谈全局网HBase八大应用场景
    如何避免HBase写入过快引起的各种问题
    阿里云MaxCompute被Forrester评为全球云端数据仓库领导者
    为了让开发者写MaxCompute SQL更爽,DataWorks 增强SQL 编辑器功能
    《CDN 之我见》原理篇——CDN的由来与调度
    Installing GCC (C++ Compiler and Development Tools)
    Gems installation
    Fedora23
  • 原文地址:https://www.cnblogs.com/WQ577098649/p/11887459.html
Copyright © 2011-2022 走看看