当前位置:Gxlcms > 数据库问题 > Python_oldboy_自动化运维之路_socket编程(十)

Python_oldboy_自动化运维之路_socket编程(十)

时间:2021-07-01 10:21:17 帮助过:48人阅读

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

也有人将socket说成ip+port,ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序,ip地址是配置到网卡上的,而port是应用程序开启的,ip与port的绑定就标识了互联网中独一无二的一个应用程序

而程序的pid是同一台机器上不同进程或者线程的标识

4.套接字的工作流程

一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。    生活中的场景就解释了这工作原理,也许TCP/IP协议族就是诞生于生活中,这也不一定。

技术分享

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

socket()模块函数用法

案例1:基于tcp的一次套接字的通信:

技术分享
# -*- coding: UTF-8 -*-
#blog:http://www.cnblogs.com/linux-chenyang/

import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #socket.AF_INET,叫做基于网络的地址家族 socket.SOCK_STREAM代表TCP协议
                                                       #相当于买手机
phone.bind((127.0.0.1,8081))                           #相当于插入卡,唯一的标示

phone.listen(5)                                        #相当于开机 5表示等待别人连接,假如我这边通话中,让他等待我完成在连接

conn,addr=phone.accept()                               #接电话conn表示线路,addr表示客户端地址
print(tcp的连接,conn)
print(客户端的地址,addr)

data=conn.recv(1024)                                   #收消息,收1024个字节大小的内容,收到的内容是bytes格式
print(from client msg:%s %data)                      #打印传过来的消息

conn.send(data.upper())                                #发消息,将传过来的值转换成大写

conn.close()                                           #挂电话
phone.close()                                          #关手机
socket服务端 技术分享
# -*- coding: UTF-8 -*-
#blog:http://www.cnblogs.com/linux-chenyang/
import socket

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

client.connect((127.0.0.1,8081))          #拨通电话

client.send(hello.encode(utf-8))        #客户发送消息

date =  client.recv(1024)
print(date)

client.close()
socket客户端 技术分享
#先执行服务端在执行客户端

#服务端输出:
tcp的连接 <socket.socket fd=268, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=(127.0.0.1, 8081), raddr=(127.0.0.1, 54345)>
客户端的地址 (127.0.0.1, 54345)
from client msg:bhello

#客户端输出:
bHELLO
执行结果

案例2:循环的socket

技术分享
# -*- coding: UTF-8 -*-
#blog:http://www.cnblogs.com/linux-chenyang/
#验证:将一个客户端断开连接,另外一个自动连接
import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)    #假如不加这行参数,假如运行过一次服务器在运行就表示端口被占用,报错
phone.bind((127.0.0.1,8081))

phone.listen(5)

while True:                             #链接循环
    conn,addr=phone.accept()
    print(client:,addr)
    while True:
        try:                                 #异常捕捉,假如有异常,然后就断掉此次循环
            data=conn.recv(1024)
            print(from client msg:%s %data)
            conn.send(data.upper())
        except Exception:                   #万能的错误,假如上面有一个异常,就执行下面的break代码
            break

    conn.close()
phone.close()
socket服务端 技术分享
# -*- coding: UTF-8 -*-
#blog:http://www.cnblogs.com/linux-chenyang/

import socket

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

client.connect((127.0.0.1,8081))          #拨通电话

while True:
    msg = input(>>:)
    client.send(msg.encode(utf-8))        #客户发送消息

    date =  client.recv(1024)
    print(date)

client.close()
socket客户端1 技术分享
# -*- coding: UTF-8 -*-
#blog:http://www.cnblogs.com/linux-chenyang/
import socket

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

client.connect((127.0.0.1,8081))          #拨通电话

while True:
    msg = input(>>:)
    client.send(msg.encode(utf-8))        #客户发送消息

    date =  client.recv(1024)
    print(date)

client.close()
socket客户端2 技术分享
#服务端
C:\Python35\python3.exe D:/pycharm/s16/day7/循环的socket服务端.py
client: (127.0.0.1, 58308)
from client msg:bls
from client msg:btest
from client msg:b\xe8\xb5\xb0\xe4\xba\x86
client: (127.0.0.1, 58313)
from client msg:bls
from client msg:bss

#客户端1:将客户端1断掉后发现服务端可以看到客户端2立马连了上来
C:\Python35\python3.exe D:/pycharm/s16/day7/循环的socket客户端2.py
>>:ls
bLS
>>:test
bTEST
>>:走了
b\xe8\xb5\xb0\xe4\xba\x86
>>:
Process finished with exit code 1

#客户端2
C:\Python35\python3.exe D:/pycharm/s16/day7/循环的socket客户端.py
>>:ls
bLS
>>:ss
bSS
执行结果

案例3:循环的socke优化

技术分享
# -*- coding: UTF-8 -*-
#blog:http://www.cnblogs.com/linux-chenyang/
#验证:将一个客户端断开连接,另外一个自动连接
import socket

phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)    #假如不加这行参数,假如运行过一次服务器在运行就表示端口被占用,报错
phone.bind((127.0.0.1,8081))

phone.listen(5)

while True:                             #链接循环
    conn,addr=phone.accept()
    print(client:,addr)
    while True:
        try:                                 #异常捕捉,假如有异常,然后就断掉此次循环
            data=conn.recv(1024)
            if not data:break               #针对linux,客户端断开链接的异常处理
            print(from client msg:%s %data)
            conn.send(data.upper())
        except Exception:                   #万能的错误,假如上面有一个异常,就执行下面的break代码
            break

    conn.close()
phone.close()
socket服务端 技术分享
# -*- coding: UTF-8 -*-
#blog:http://www.cnblogs.com/linux-chenyang/

import socket

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

client.connect((127.0.0.1,8081))          #拨通电话

while True:
    msg = input(>>:)
    if not msg:continue                     #假如不输入这条内容,当msg直接为空时,会发生阻塞,客户端send一个空,服务器会一直等着收,不会send
    client.send(msg.encode(utf-8))        #客户发送消息
    print(===========has send=========)

    date =  client.recv(1024)
    print(===========has recv=========)
    print(date)

client.close()
socket客户端

案例4:socke模拟远程执行命令

技术分享
import socket
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)    #假如不加这行参数,假如运行过一次服务器在运行就表示端口被占用,报错
phone.bind((127.0.0.1,8081))
phone.listen(5)
while True:
    conn,addr=phone.accept()
    print(client:,addr)
    while True:
        try:
            cmd=conn.recv(1024)
            print(-------shou dao--- )
            if not cmd:break
            print(from client msg:%s %cmd)

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

            err=res.stderr.read()
            if err:
                back_msg=err
            else:
                back_msg=res.stdout.read()

            conn.sendall(back_msg)

        except Exception:
            break

    conn.close()
phone.close()
socket服务端 技术分享
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((127.0.0.1,8081))

while True:
    cmd = input(>>:).strip()
    if not cmd:continue

    client.send(cmd.encode(utf-8))
    print(send chenggong)
    res = client.recv(1024)
    print(res.decode(gbk))
socke客户端 技术分享
#服务端
client: (127.0.0.1, 61320)
-------shou dao--- 
from client msg:bdir

#客户端
C:\Python35\python3.exe D:/pycharm/s16/day7/远程执行命令客户端.py
>>:dir
send chenggong
 驱动器 D 中的卷是 Data
 卷的序列号是 EE42-C3C3

 D:\pycharm\s16\day7 的目录

2017/03/08  21:35    <DIR>          .
2017/03/08  21:35    <DIR>          ..
2017/03/08  17:23               337 socket客户端.py
2017/03/08  17:23             1,222 socket服务端.py
2017/03/08  14:39               697 为什么要有类,对象.py
2017/03/07  17:24               690 多态与多态性.py
2017/03/07  19:22               780 子类调用父类的方法.py
2017/03/06  17:51             1,268 对象之间的交互.py
2017/03/07  17:58             1,532 封装.py
2017/03/08  20:06               652 循环的socket客户端.py
2017/03/08  17:49               380 循环的socket客户端2.py
2017/03/08  20:09             1,062 循环的socket服务端.py
2017/03/07  15:59               939 抽象类.py
2017/03/07  15:03               741 接口与归一化设计.py
2017/03/07  18:57             1,376 特性_set_get.py
2017/03/07  18:23             1,337 特性(property).py
2017/03/06  16:09                 2 笔记
2017/03/06  17:39             1,719 类与对象.py
20



#备注:假如执行的时候客户端发出去了,服务端没有收到,但是已经连接上了,已经打印客户端的信息,那么就换个端口试试,原因:未解
执行结果

 

Python_oldboy_自动化运维之路_socket编程(十)

标签:字节   pytho   端口被占用   指定   pipe   全世界   网络   断开连接   exce   

人气教程排行