• Socket


    TCP/IP:(通信)
    tcp/ip协议是主机接入互联网以及接入换联网的两台主机通信的标准

    实例:

      

    import socket
    ip_port=('127.0.0.1',9999)
    #买手机
    s=socket.socket()
    
    #拨号
    s.connect(ip_port)
    
    while True:
    #发消息
    send_data=input(">>:")
    if send_data == '':continue
    s.send(bytes(send_data,encoding='utf8'))
    if send_data == 'e':break
    #收消息
    recv_data=s.recv(1024)
    #挂电话
    s.close()
    
    socket _client
    socket_client
    import socket
    ip_port=('127.0.0.1',9999)
    #买手机
    s=socket.socket()
    #买卡
    s.bind(ip_port)
    #开机
    s.listen(5)
    #待机
    conn,aad=s.accept()
    while True:
        try:
            #收消息
            recv_data=conn.recv(1024)
            if str(recv_data,encoding='utf8') == 'e':break
            print(str(recv_data,encoding='utf8'))
            #发消息
            send_data=recv_data
            conn.send(send_data)
        except Exception:
            break
    #挂电话
    conn.close()
    socket_server

     

    单线程:

    import socket
    ip_port=('127.0.0.1',9999)
    #买手机
    s=socket.socket()
    #买卡
    s.bind(ip_port)
    #开机
    s.listen(1)  #连接数
    while True:
        #待机
        conn,aad=s.accept()
        while True:
            try:
                #收消息
                recv_data=conn.recv(1024)
                if str(recv_data,encoding='utf8') == 'e':break
                print(str(recv_data,encoding='utf8'))
                #发消息
                send_data=recv_data
                conn.send(send_data)
            except Exception:
                break
        #挂电话
        conn.close()
    单线程

       s.listen(n)    本身可以连接一个,n为挂起连接数

      服务端出现端口占用 ,修改端口号即可

      粘包问题:若发送大于1024  一次接收不完,被会出现此问题,下一次会打印未接受完的内容

        解决办法:先recv()一个长度,写循环接收

        具体解决办法如下:    

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import socket
    import subprocess #导入执行命令模块
    ip_port=('127.0.0.1',9999) #定义元祖
    #买手机
    s=socket.socket()  #绑定协议,生成套接字
    s.bind(ip_port)    #绑定ip+协议+端口:用来唯一标识一个进程,ip_port必须是元组格式
    s.listen(5)        #定义最大可以挂起胡链接数
    #等待电话
    while True:  #用来重复接收新的链接
        conn,addr=s.accept()   #接收客户端胡链接请求,返回conn(相当于一个特定胡链接),addr是客户端ip+port
        #收消息
        while True: #用来基于一个链接重复收发消息
                try: #捕捉客户端异常关闭(ctrl+c)
                    recv_data=conn.recv(1024) #收消息,阻塞
                    if len(recv_data) == 0:break #客户端如果退出,服务端将收到空消息,退出
    
                    #发消息
                    p=subprocess.Popen(str(recv_data,encoding='utf8'),shell=True,stdout=subprocess.PIPE) #执行系统命令,windows平
                                                                                                          # 台命令的标准输出是gbk编码,需要转换
                    res=p.stdout.read()   #获取标准输出
                    if len(res) == 0:   #执行错误命令,标准输出为空,
                        send_data='cmd err'
                    else:
                        send_data=str(res,encoding='gbk')  #命令执行ok,字节gbk---->str---->字节utf-8
    
                    send_data=bytes(send_data,encoding='utf8')
    
    
                    #解决粘包问题
                    ready_tag='Ready|%s' %len(send_data)
                    conn.send(bytes(ready_tag,encoding='utf8')) #发送数据长度
                    feedback=conn.recv(1024)  #接收确认信息
                    feedback=str(feedback,encoding='utf8')
    
                    if feedback.startswith('Start'):
                        conn.send(send_data)  #发送命令的执行结果
                except Exception:
                    break
        #挂电话
        conn.close()
    粘包问题_server
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author:Alex Li
    import socket
    ip_port=('127.0.0.1',9999)
    #买手机
    s=socket.socket()
    #拨号
    s.connect(ip_port)  #链接服务端,如果服务已经存在一个好的连接,那么挂起
    
    while True:        #基于connect建立的连接来循环发送消息
        send_data=input(">>: ").strip()
        if send_data == 'exit':break
        if len(send_data) == 0:continue
        s.send(bytes(send_data,encoding='utf8'))
    
        #解决粘包问题
        ready_tag=s.recv(1024) #收取带数据长度的字节:Ready|9998
        ready_tag=str(ready_tag,encoding='utf8')
        if ready_tag.startswith('Ready'):#Ready|9998
            msg_size=int(ready_tag.split('|')[-1])  #获取待接收数据长度
        start_tag='Start'
        s.send(bytes(start_tag,encoding='utf8')) #发送确认信息
    
        #基于已经收到的待接收数据长度,循环接收数据
        recv_size=0
        recv_msg=b''
        while recv_size < msg_size:
            recv_data=s.recv(1024)
            recv_msg+=recv_data
            recv_size+=len(recv_data)
            print('MSG SIZE %s RECE SIZE %s' %(msg_size,recv_size))
    
        print(str(recv_msg,encoding='utf8'))
        #挂电话
    s.close()
    粘包问题_client

     多线程

    import socketserver
    
    class MyServer(socketserver.BaseRequestHandler):
        def handle(self):
            # print self.request,self.client_address,self.server
              #conn
            self.request.sendall(bytes('欢迎致电 10086,请输入1xxx,0转人工服务.',encoding="utf-8"))
            while True:
                data = self.request.recv(1024)
                print("[%s] says:%s" % (self.client_address,data.decode() ))
                self.request.sendall(data.upper())
    
    if __name__ == '__main__':
        server = socketserver.ThreadingTCPServer(('127.0.0.1',8009),MyServer)
        server.serve_forever()
    server
    import socket
    ip_port=('127.0.0.1',8009)
    #买手机
    s=socket.socket()
    #拨号
    s.connect(ip_port)
    #发送消息
    welcome_msg = s.recv(1024)
    print("from server:",welcome_msg.decode())
    while True:
        send_data=input(">>: ").strip()
        if len(send_data) == 0:continue
        s.send(bytes(send_data,encoding='utf8'))
    
        #收消息
        recv_data=s.recv(1024)
        print(str(recv_data,encoding='utf8'))
        #挂电话
    s.close()
    clients

       多线程ssh:

    import socketserver
    import subprocess
    class MyServer(socketserver.BaseRequestHandler):
        def handle(self):
            # print self.request,self.client_address,self.server
            self.request.sendall(bytes('欢迎致电 10086,请输入1xxx,0转人工服务.',encoding="utf-8"))
            while True:
                data = self.request.recv(1024)
                if len(data) == 0:break
                print("[%s] says:%s" % (self.client_address,data.decode() ))
                #self.request.sendall(data.upper())
                cmd = subprocess.Popen(data.decode(),shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
                cmd_res =cmd.stdout.read()
                if not cmd_res:
                   cmd_res = cmd.stderr.read()
                if len(cmd_res) == 0: #cmd has not output 
                   cmd_res = bytes("cmd has output",encoding="utf-8")
                self.request.send(cmd_res )
    
    
    if __name__ == '__main__':
        server = socketserver.ThreadingTCPServer(('0.0.0.0',8009),MyServer)
        server.serve_forever()
    多线程ssh_server
  • 相关阅读:
    【Oracle】优化器之RBO与CBO
    【Oracle11g】16_数据字典和动态性能视图
    AXI总线介绍
    Verilog 加法器和减法器(8)-串行加法器
    状态机实例-寄存器拷贝
    状态机状态最小化
    vcs+Makefile实现简单的testbench
    quartus II输入原理图及仿真步骤
    Directx11代码下载
    触发器的时序参数与时序分析
  • 原文地址:https://www.cnblogs.com/zhaozhenguo666/p/5637897.html
Copyright © 2020-2023  润新知