zoukankan      html  css  js  c++  java
  • 基于TCP协议的socket套接字编程

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

    一、什么是Scoket

    Scoket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

    所以,我们无需深入理解tc/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。

    • 注意:也有人将scoket说成ip+port,ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的应用程序,ip地址是配置到网卡上的,而port是应用程序开启的,ip和port的绑定就标识了互联网独一无二的一个应用程序,而程序的pid是同一台机器上的不同进程或者线程的标识。

    二、基于TCP协议的套接字编程(简单)

    客户端

    import socket
    
    client = socket.socket()  # 拿电话
    
    # 拨电话,指定服务器ip号和端口号
    client.connect(('127.0.0.1',8080))
    
    client.send(b'hello world!')  # 通信发送信息
    data = client.recv(1024)  # 接收信息
    print(data)
    client.close()  # 挂点电话
    

    服务端

    import socket
    
    
    server = socket.socket() # 买手机,不传参数默认用的是TCP协议
    # 插入手机卡
    server.bind(('127.0.0.1',8080))  # 127.0.0.1本机回还地址 特点:只能识别自己
    server.listen(5)  # 开机,半连接池,限制的是请求数
    
    print('start....')
    # 接听电话
    conn,addr = server.accept() # (三次握手建立的双向连接,(客户端的ip和端口号))
    
    data = conn.recv(1024)  # 最大接收的字节数
    print(data)
    conn.send(b'hello baby~')  # 发送信息
    
    # 挂掉电话
    conn.close()
    # 关机
    server.close()
    

    三、基于TCP协议的套接字编程(循环)

    服务端:

    import socket
    """
    服务端
        固定的ip地址和port
        24小时不间断提供服务
    """
    
    server = socket.socket()
    server.bind(('127.0.0.1',8080))  # 绑定ip和port
    server.listen(5)  # 半连接池
    
    while True:
        conn,addr = server.accept() # 等别人来,conn就类似于双向通道
        print(addr)  # ('127.0.0.1',5132)客户端的地址
        while True:
            # 客户端断开连接后,服务器会报错使用异常处理。
            try:
                data = conn.recv(1024)
                print(data)  # b"" 针对mac与linux客户端异常退出之后,服务端不会报错,只会一直收b""
                if len(data) == 0:break
                conn.send(data.upper())
            except ConnectionResetError as e:
                print(e)
                break  # 不中断的话会一直打印错误信息
    
        conn.close()
    

    客户端

    import socket
    
    client = socket.socket()
    
    client.connect(('127.0.0.1',8080))
    
    while True:
        msg = input('>>>:').encode('utf-8')
        if len(msg) == 0:continue
        # if not msg:continue
        client.send(msg)  # 发送的信息可以自己输入
        data = client.recv(1024)
        print(data)
    

    在服务器连接客户端1时,虽然也能监听到客户端2,但不能给客户端2返回消息,将客户端1关闭后即断开连接。给客户端2返回数据。

    四、地址占用问题

    有的同学在重启服务端时,可能会遇到:

    这个是由于你的服务端仍然存在四次挥手的time_wait状态在占用地址。(如果不懂,请深入研究1.tcp三次握手,四次挥手 2.syn洪水攻击 3.服务器高并发情况下会有大量的time_wait状态的优化方法)

    # 加入一条socket配置,重用ip和端口
    server = socket(AF_INET,SOCK_STREAM)
    server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
    server.bind(('127.0.0.1',8080))
    
  • 相关阅读:
    set集合 浅层拷贝会和深层拷贝
    "is"与"=="
    元组和字典
    运算符和列表
    Python 基础语法
    supervisor 安装配置详解
    如何运行vue项目
    过目不忘JS正则表达式
    vue Bus总线
    Robot Framework 环境安装(一)
  • 原文地址:https://www.cnblogs.com/zuihoudebieli/p/11331775.html
Copyright © 2011-2022 走看看