zoukankan      html  css  js  c++  java
  • python socket

    Socket

     

    socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

    socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

    socket和file的区别:

    • file模块是针对某个指定文件进行【打开】【读写】【关闭】
    • socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】

       利用socket实现简单双人对话场景

      import socket
      
      ip_port = ('127.0.0.1',9999)
      
      sk = socket.socket()
      sk.bind(ip_port)
      sk.listen(5)   # 最大允许连接5个?
      
      while True:
          print ('server waiting...')
          conn,addr = sk.accept()  ##等待用户连接操作,addr表示获取客户端的ip和端口 conn表示生成实例
          while True:
              try:
                  client_data = conn.recv(1024) # 阻塞状态 接受客户端的数据 1024代表字节
                  # if not client_data.decode():break
                  print (str(client_data,'utf-8'))
                  A=input('>>>:')
                  conn.sendall(bytes(bytes(A,'utf8')))
              except Exception:
                  print("error")
                  break
      socket server
      import socket
      ip_port = ('127.0.0.1',9999)
      
      sk = socket.socket()
      sk.connect(ip_port)
      while True:
          user_input = input('>>:'.strip())
          sk.sendall(bytes(user_input,'utf-8'))
          server_reply = sk.recv(1024)
          print (str(server_reply,'utf-8'))
      socket client

       注意 上面socket server 的recv接受的不是字节 是字符

     通过socket实现ssh的功能以及大数据的传输:

    # 一些简单的命令,可直接通过socket传入,如果一些返回结果数据较多的命令,不做处理的话,返回的消息就会错乱

    linux_socket_server

    #!/usr/bin/env python3.5
    # Auth -chenjinpeng-
    import socket,subprocess,time
    
    Ip_port = ('127.0.0.1',9999)
    
    Ftp = socket.socket()
    Ftp.bind(Ip_port)
    Ftp.listen(5) # 最大允许连5个?
    
    while True:
            print ("server waiting...")
            conn,addr = Ftp.accept() #等待用户连接操作,addr表示获取客户端的ip和端口 conn表示生成实例
    
            while True:
                    #try:
                    client_data = conn.recv(1024) # 收客户端的消息 阻塞
                    if not client_data:break # 如果接受不到消息 则退出循环
                    cmd = client_data.decode().strip() # 将获取到的消息进行转码,将bytes转换为str用decode
                    cmd_call = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE) # 将读取到的命令通过管道符进行输出到变量
                    #Server_input = input("S >>>:").strip()
                    cmd_result = cmd_call.stdout.read() # 获取命令的结果(此执行结果为bytes类型)
                    if len(cmd_result) == 0:
                            cmd_result = b"cmd execution has no output!"
                    cmd_len=bytes(str("cmd_long|%s"%str(len(cmd_result))),'utf8')  # 第一次首先将结果的长度发过去
                    conn.sendall(cmd_len)
                    ack=conn.recv(50) # 确认用户收到后回复。进行下一步操作
                    if ack:
                            if ack.decode() == "ack":
                                    conn.sendall(cmd_result) # 因为为bytes类型 直接发送
                    else:break
            conn.close()

    linux_csocket_client

    #!/usr/bin/env python3.5
    # - Auth chenjinpeng -
    
    import socket
    Ip_port = ('127.0.0.1',9999)
    
    Client = socket.socket()
    Client.connect(Ip_port)
    
    #Client.sendall(bytes('请求占领地球','utf8'))
    #Server_reply = Client.recv(1024)
    #print (str(Server_reply,'utf8'))
    while True:
            User_input = input(">>>:").strip()
            if len(User_input) == 0:continue
            if User_input == 'q':break
    
            Client.sendall(bytes(User_input,'utf8'))
            cmd_result_msg=Client.recv(100) # 第一次接受的是服务器发来的字符串长度
            cmd_result_len=str(cmd_result_msg.decode()) # 转换str
            cmd_result_len_result=cmd_result_len.split("|") # 分割列表
            if cmd_result_len_result[0] == "cmd_long": # 判断是否是分割的数据
                    cmd_result_size = int(cmd_result_len_result[1]) # 取出返回的字符长度
            else:
                    print ("error !")
                    continue
            Client.sendall(bytes("ack",'utf8')) # 发送ack确认消息,服务端正式开始发送数据
            cmd_len_default=0 # 定义输出读取的字符长度
            res = '' # 定义空字符 循环增加每次读取的字符
            while cmd_len_default < cmd_result_size: # 判断字符是否读完。如果小于服务端发送过来的长度,则代表没接收完
                    Server_reply = Client.recv(500) # 每次收取500字符
                    cmd_len_default+=len(Server_reply) # 每次字符长度加上已经读取的字符长度
                    res += str(Server_reply.decode()) # 读取过的字符相加,循环完毕后统一打印
            else:
                    print (res)
                    print ("-------last time-----")
    Client.close()
             
  • 相关阅读:
    Linux调整时区和同步时间
    wget命令
    apt-get损坏修复
    apt-get卸载命令
    apt-get命令
    ps命令
    卸载Ambari
    YARN Registry DNS启动提示“53端口被占用”错误的解决方法
    反转链表,时间复杂度O(n),空间复杂度O(1)
    简易版之最短距离
  • 原文地址:https://www.cnblogs.com/Chen-PY/p/5230454.html
Copyright © 2011-2022 走看看