Python-简单的套接字通信

一、socket

什么是socket

socket是用于在两个基于TCP/IP协议的应用程序之间相互通信。最早出现在UNIX系统中,是UNIX系统主要的信dao息传递方式。在WINDOWS系统中,SOCKET称为WINSOCK。

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。

简单来讲,Socket是网络应用程序接口,是应用层到传送层的接口。也就是用户进程,与系统内核的接口。

二、基于tcp协议实现简单套接字通信

将套接字通信比喻为手机通信,那么我们现在有客户端与服务端两个部分。

客户端

1.大家都需要买手机,即创建一个socket对象。

2.对于客户端来说,有了手机(socket对象之后)就可以拨打电话了,我们需要知道电话号码,即对方的ip地址与端口号,因为ip地址+端口号可以标记世界上独一无二的一个软件。127.0.0.1表示本地回环地址,一般在自己测试的时候使用,防止外部人员的干扰。

3.拨打完电话之后就可以开始通话了,即传输内容,因为我们不可能说一句话就结束通话,所以使用循环。

4.在结束通话后,我们需要关闭手机。回收资源

# 客户端
import socket

# 1、买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # SOCK_STREAM=》TCP协议

# 2、拨电话
phone.connect(("127.0.0.1", 8080))

# 3、发/收消息=>通信循环
while True:
    msg = input(">>: ").strip()
    phone.send(msg.encode('utf-8'))
    data = phone.recv(1024)
    print("服务端返回的数据:", data.decode('utf-8'))

# 4、关闭
phone.close()

服务端

1.无论是客户端还是服务端,都需要一个手机,创建一个socket对象。

2.服务端需要声明自己的手机号码,让客户打过来。即确定自己的ip地址与端口号

3.开机,设定半连接池的大小。

4.等客户电话,若有电话打进来我们需要先接通,即conn, client_addr = phone.accept()

5.开始通信

6.通信结束,应该先挂断电话,即conn.close()

7.关闭手机,回收资源

"""
服务端应该满足的特性:
    1、一直对外提供服务
    2、并发地提供服务
"""

import socket

# 1、买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # SOCK_STREAM=》TCP协议

# 2、插手机卡
phone.bind(("127.0.0.1", 8080))  # 本地回环

# 3、开机
phone.listen(5)
print('starting %s:%s' %("127.0.0.1", 8080))

# 4、等电话链接=>链接循环
while True:
    conn, client_addr = phone.accept()
    print(client_addr)
    # 5、收/发消息=>通信循环
    while True:
        try:
            data = conn.recv(1024)  # 最大接收的字节个数
            if len(data) == 0:  # 针对linux系统
                break
            print("收到的客户端数据:", data.decode('utf-8'))
            conn.send(data.upper())
        except Exception:  # 针对windows系统
            break

    # 6、关闭
    conn.close()  # 挂电话
phone.close()  # 关机

远程执行命令(简易版)

服务端

"""
服务端应该满足的特性:
    1、一直对外提供服务
    2、并发地提供服务
"""

import socket
import subprocess

# 1、买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # SOCK_STREAM=》TCP协议

# 2、插手机卡
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 就是它,在bind前加

phone.bind(("127.0.0.1", 8080))  # 本地回环

# 3、开机
phone.listen(5)
print('starting %s:%s' % ("127.0.0.1", 8080))

# 4、等电话链接=>链接循环
while True:
    conn, client_addr = phone.accept()
    print(client_addr)
    # 5、收/发消息=>通信循环
    while True:
        try:
            cmd = conn.recv(1024)  # 最大接收的字节个数
            if len(cmd) == 0:  # 针对linux系统
                break

            obj = subprocess.Popen(cmd.decode('utf-8'),
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE
                                   )

            res=obj.stdout.read()+obj.stderr.read()  # ???
            print(res)
            conn.send(res)
        except Exception:  # 针对windows系统
            break

    # 6、关闭
    conn.close()  # 挂电话
phone.close()  # 关机

客户端

import socket

# 1、买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # SOCK_STREAM=》TCP协议

# 2、拨电话
phone.connect(("127.0.0.1", 8080))

# 3、发/收消息=>通信循环
while True:
    cmd = input("[root@localhost]# ").strip()
    phone.send(cmd.encode('utf-8'))
    data = phone.recv(1024)
    print(data.decode('gbk'))

# 4、关闭
phone.close()
posted @ 2020-12-01 08:31  王寄鱼  阅读(206)  评论(0编辑  收藏  举报