• socket套接字


    socket套接字

    端口号:

    ​ 0-1024: 禁用,操作系统在用

    ​ 用8000以上的

    软件固定的端口号:

    ​ django: 8000

    ​ mysql: 3306

    ​ redis: 6379

    ​ flask: 5000

    ​ tomcat:8080

    ​ mongodb:27017

    1.TCP协议:三次握手,四次挥手

    ​ TCP协议建立双向通道

    ​ 三次握手,建立连接:

    ​ 1.客户端向服务端发送建立连接的请求

    ​ 2.服务端返回接收请求的信息给客户端,并且发送送往客户端建立连接的请求

    ​ 3.客户端接收到服务端发来的请求,返回同意信息给服务端,完成双向连接

    反馈机制:

    客户端往服务端发送请求,服务端必须返回响应,告诉客户端收到请求了,并且将服务端的数据一并返回给客户端

    一次请求必须要有一次响应

    缺点:

    ​ 洪水攻击:

    ​ 指的是通过伪造大量的请求,往对方服务器发送请求,导致对方服务器响应跟不上,以至于瘫痪

    ​ 在linux系统中有一个参数可以限制

    ​ 半连接池listen:限制用户在同一时间段内的访问数量

    ​ 四次挥手,断开连接

    1.客户端向服务端发送断开连接的请求

    2.服务端返回收到请求的信息给客户端

    3.服务器确认所有的数据接收完成后,再发送同意断开连接的请求给客户端,同时发送断开连接的请求

    4.客户端返回同意断开连接的请求,给服务端

    socket套接字通信:

    什么是socket:

    socket是一个模块,又称套接字,用来封装互联网协议(应用层以下的层)

    为什么要有socket?

    socket可以实现,互联网协议应用层以下的层的工作,提高开发效率

    怎么使用socket?

    import socket

    写socket套接字:

    client和server

    粘包问题:

    1.无法确认对方发过来数据的大小

    2.再发送数据间隔短并且数据量小的情况下,会将所有的数据一次性发送

    解决: 确认对方数据的大小

    解决粘包问题(struct模块)

    无论哪一段先发送数据

    客户端:

    1)先制作报头,并发送(struct)

    2)发送真实数据

    服务端:

    1)接收报头,并解包获取真实数据长度

    2)根据真实数据长度接收真实数据

    rev(真实数据长度)

    server端
    
    import socket
    
    server = socket.socket()
    
    server.bind(
        ('127.0.0.1', 9898)
    )
    
    # 半连接池
    server.listen(5)  # 实际上可以允许6个访问
    
    print(
        'serve is running!'
    )
    
    # conn:指的是服务端通往客户端的管道
    # 接收客户端链接
    conn, addr = server.accept()
    
    print(addr)
    
    # 接收内容
    ret = conn.recv(1024)
    print(
        ret.decode('utf-8')
    )
    
    # 发送数据
    conn.send('你好'.encode('utf-8'))
    
    conn.close()
    
    
    client端
    
    import socket
    
    client = socket.socket()
    
    client.connect(
        ('127.0.0.1', 9898)
    )
    
    print(
        'client is running!'
    )
    
    # 必须发送bytes的数据
    # client.send('hello'.encode('utf-8'))
    client.send('hello'.encode('utf-8'))
    
    # 接收数据
    ret = client.recv(1024)
    print(ret.decode('utf-8'))
    
    client.close()
    
    
    结果:
    server端:
    serve is running!
    ('127.0.0.1', 63794)
    hello
    
    client端:
    client is running!
    你好
    
    
    完整的:
    
    server端
    
    import socket
    
    server = socket.socket()
    
    server.bind(
        ('127.0.0.1', 9556)
    )
    
    print('server is running!')
    
    # 半连接池
    server.listen(5)
    
    # 循环实现可以接受多个用户访问
    while True:
        conn, addr = server.accept()
        print(addr)
    
        while True:
            # 抛出异常处理
            try:
                # 接收客户端发送的数据
                data = conn.recv(1024)
                data = data.decode('utf-8')
                if len(data) == 0:
                    break
                if data == 'q':
                    break
                print(data)
    
                # 再由服务端给客户端发送数据
                send_data = input('服务端》》:').strip()
                conn.send(send_data.encode('utf-8'))
            except Exception as e:
                print(e)
    
        conn.close()
        
    client端:
    
    import socket
    
    client = socket.socket()
    
    client.connect(
        ('127.0.0.1', 9556)
    )
    
    print('client is running!')
    
    while True:
        # 用户输入
        send_data = input('客户端》》:').strip()
        # 客户端发送信息
        client.send(send_data.encode('utf-8'))
        # 客户端再接收服务器端发送过来的数据
        data = client.recv(1024)
    
        if data.decode('utf-8') == 'q':
            break
    
        if len(data) == 0:
            break
        # 打印数据信息
        print(data.decode('utf-8'))
    
    client.close()
    
    
    运行结果:
    client:
    
    client is running!
    客户端》》:你是谁
    我是你爸爸
    客户端》》:去你的
    fuck your mouth
    客户端》》:
    
    server:
    
    server is running!
    ('127.0.0.1', 64030)
    你是谁
    服务端》》:我是你爸爸
    去你的
    服务端》》:fuck your mouth
    
    
    解决粘包问题:
    client:
    
    import socket
    import struct
    import json
    
    client = socket.socket()
    
    client.connect(
        ('127.0.0.1', 9000)
    )
    
    while True:
    
        movie_name = input('请输入上传电影的名字: ')
    
        # 伪装电影真实数据
        movie_len = 1000000
    
        send_dic = {
            'movie_name': movie_name,
            'movie_len': movie_len
        }
    
        # 序列化
        json = json.dumps(send_dic)
        print(json)
        print(json.encode('utf-8'))
        print(len(json.encode('utf-8')))
    
        json_bytes = json.encode('utf-8')
    
        # 做一个报头
        header = struct.pack('i', len(json_bytes))
    
        # 先发送报头
        client.send(header)
    
        # 后发送真实数据
        client.send(json_bytes)
    
    
    server:
        import socket
    import json
    import struct
    
    server = socket.socket()
    
    server.bind(
        ('127.0.0.1', 9000)
    )
    
    server.listen(5)
    
    while True:
        conn, addr = server.accept()
        print(addr)
    
        while True:
            try:
                # 获取客户端传过来的报头
                header = conn.recv(4)
    
                # 解包获取真实数据长度
                json_len = struct.unpack('i', header)[0]
    
                # 接收json(dict)的真实长度
                json_bytes_data = conn.recv(json_len)
    
                # 将bytes类型数据转为json数据
                json_data = json_bytes_data.decode('utf-8')
    
                # 反序列化  json ---> dict
                back_dic = json.loads(json_data)
                print(back_dic)
                print(back_dic.get('movie_len'))
    
                # 准备接收真实数据
                # movie_data = conn.recv(back_dic.get('movie_len'))
                # print(movie_data)
    
            except Exception as e:
                print(e)
                break
    
    
        conn.close()
    
    
  • 相关阅读:
    java第二周的学习知识
    java第一次课
    今天晚上有事,代码假期完成。
    [leetcode] Minimum Path Sum
    java访问权限整理
    java IO整理-File
    java初始化顺序
    enum使用整理
    工厂模式总结
    java IO-流
  • 原文地址:https://www.cnblogs.com/godlover/p/11991802.html
Copyright © 2020-2023  润新知