• Python -- socket套接字


    8.6 socket 套接字

    什么是socket套接字?

    socket套接字充当的就是内置模块的角色.
    socket套接字,它是存在于传输层与应用层之间的抽象层
    # 作用	
    1. 避免学习各层的接口,以及协议的使用,socket已经封装好了所有的接口直接使用这些接口或者方法即可,使用起来方便,提升开发效率.
    2. socket就是一个模块,通过使用学习模块提供的功能,建立客户端与服务端的通信,使用方便
    

    五层协议:从传输层开始及以下,都是操作系统帮助我们封装的各种head

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

    8.6.1 基于TCP协议的socket

    先从服务端说起.服务器端先初始化socket,然后与端口绑定(bild),对端口进行监听(listen),调用accept阻塞,等待客户端连接.这个时候如果在有个客户端初始化一个socket,然后连接服务器(connect),如果连接成功,这时客户端与服务端的连接就建立了.客户端发送数据请求,服务器端接收请求并处理请求,然后回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束.

    1. 单个客户通信
    # 服务端
    
    import socket
    # 1.创建socket对象
    phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2.绑定ip地址和端口
    phone.bind(('127.0.0.1',6868))
    # 3.监听
    phone.listen(5)
    # 4.接收连接
    conn,addr = phone.accept()
    print(conn,addr)
    # 5.接收消息
    from_client_data = conn.recv(1024)
    print(f'来自客户端{addr}的信息{from_client_data.decode("utf-8")}')
    # 6.发送消息
    to_client = input('>>>')
    conn.send(to_client.encode('utf-8'))
    
    conn.close()
    phone.close()
    
    # 客户端
    import socket
    # 1.创建socket对象
    phone = socket.socket()
    # 2.连接服务器ip和端口
    phone.connect(('127.0.0.1',6868))
    # 3.发消息
    to_server = input('>>>')
    phone.send(to_server.encode('utf-8'))
    # 4.接收消息
    from_server_data = phone.recv(1024)
    print(f'来自服务端的消息:{from_server_data.decode("utf-8")}')
    phone.close()
    
    2. 通信,连接循环
    # 服务端
    import socket
    
    phone = socket.socket()
    phone.bind(('127.0.0.1',8888))
    phone.listen(3)
    while 1:
        conn,addr = phone.accept()
        while 1:
            try:
                from_client_data = conn.recv(1024)
                if from_client_data == b'q':
                    break
                print(f"来自客户端{addr}的消息:{from_client_data.decode('utf-8')}")
                to_client = input('>>>').strip()
                conn.send(to_client.encode('utf-8'))
            except ConnectionResetError:
                break
        conn.close()
    phone.close()
    
    
    # 客户端
    import socket
    
    phone = socket.socket()
    phone.connect(('127.0.0.1',6688))
    while 1:
        to_server = input('>>>').strip()
        if to_server.upper() == 'Q':
            phone.send('q'.encode('utf-8'))
            break
        phone.send(to_server.encode('utf-8'))
        from_server_data = phone.recv(1024)
        print(f'来自服务端的信息{from_server_data.decode("utf-8")}')
    
    phone.close()
    
    3. 远程执行命令
    # 服务端
    import socket
    import subprocess
    phone = socket.socket()
    phone.bind(('127.0.0.1',6666))
    phone.listen(3)
    while 1:
        conn,addr = phone.accept()
        while 1:
            try:
                cmd = conn.recv(1024)
                ret = subprocess.Popen(cmd.decode('utf-8'),
                                       shell = True,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
                result= ret.stdout.read() + ret.stderr.read()
                conn.send(result)
            except ConnectionResetError:
                break
        conn.close()
    phone.close()
    
    # 客户端
    import socket
    phone = socket.socket()
    phone.connect(('127.0.0.1',6666))
    
    while 1:
        cmd = input('>>>').strip()
        phone.send(cmd.encode('utf-8'))
        result = phone.recv(1024)
        print(result.decode('gbk'))
    phone.close()
    

    8.6.2 基于UDP协议的socket

    ​ 先从服务器端说起。服务端先初始化Socket,然后与端口绑定(bind),recvform接收消息,这个消息有两项,消息内容和对方客户端的地址,然后回复消息时也要带着你收到的这个客户端的地址,发送回去,最后关闭连接,一次交互结束.

    udp是无链接的,先启动哪一端都不会报错

    # 服务端
    import socket
    udp_server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    udp_server.bind(('127.0.0.1',9000))
    while 1:
        from_client_date = udp_server.recvfrom(1024) # 接收到的是一个元组形式的数据(bytes类型,(IP,端口)
        print(f'来自{from_client_date[1]}的消息:{from_client_date[0].decode("UTF-8")}')
        to_client_data = input('>>>')
        udp_server.sendto(to_client_data.encode('utf-8'),from_client_date[1])
    
    # 客户端
    import socket
    udp_client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    while 1:
        to_server_data = input('>>>').strip()
        udp_client.sendto(to_server_data.encode('utf-8'),('127.0.0.1',9000)) # 发送信息加上接收方IP和端口
        from_server_data = udp_client.recvfrom(1024)
        print(f'来自{from_server_data[1]}的消息:{from_server_data[0].decode("utf-8")}')
    

  • 相关阅读:
    简单实现java线程池 阿里
    下载安装mysql的一些坑 阿里
    [ZZ]]文艺表年装B指南
    台湾前十大科技公司拼不过三星(往后一点三星都不要买啦!)
    [不是面经,胜似面经]条条大路通Google
    ubuntu 下PDA同步解决(SynCE, OpenSync)
    android整体印象
    关系图:Linux演化图,Ubuntu应用图
    linux 版本中 i386/i686/x8664/pcc 等... 的区别
    一个计算机高手的成长历程【转】
  • 原文地址:https://www.cnblogs.com/Agoni-7/p/11234817.html
Copyright © 2020-2023  润新知