zoukankan      html  css  js  c++  java
  • python——网络编程

    socket

    简单讲先是server端发布一个服务,提供端口和IP,监听起来,就OK了。通过socket.send(bytes)给客户端发送消息,通过socket.recv(bytes)接收客户端的数据,进行处理

    #!/user/bin/env python
    # -*- coding:utf-8 -*-
    # 模拟ssh
    
    import socket, subprocess
    
    #获取socket对象
    s = socket.socket()
    
    #获取socket参数
    ip_port = (socket.gethostname(), 1234)
    ip_port = (socket.gethostname(), 1234)
    #创建服务
    s.bind(ip_port)
    #开启监听
    s.listen(5)
    while True:
        #等待连接
        conn, addr = s.accept()
        print(conn.getsockname(),"连接服务")
        while True:
    
            #获取连接消息
            res = conn.recv(1024)
            send_data = res
            p = subprocess.Popen(str(res, encoding='utf-8'), shell = True, stdout = subprocess.PIPE)
            send_data = p.stdout.read()
            print(type(send_data))
            if len(res) == 0:
                print(conn.getsockname(),'断开服务')
                break
            if send_data:
                send_data = str(send_data,encoding='gbk')
            else:
                send_data = 'command error!'
            print(send_data)
            #发送消息
            len_data = len(bytes(send_data,encoding='utf-8'))
            conn.send(bytes("%d"%len_data, encoding='utf-8'))
            to_recv = str(conn.recv(1024),encoding = 'utf-8')
            print(to_recv)
            if to_recv == 'Y' or to_recv == 'y':
                conn.send(bytes(send_data,encoding='utf-8'))
            else:
                print('不接收')
                conn.send(bytes("OK!不接收!",encoding='utf-8'))
        #关闭连接
        conn.close()

    然后客户端根据提供的端口和IP去连接,通过socket.spend(bytes)发送数据给服务端,通过socket.recv(bytes)接收服务端数据

    #!/user/bin/env python
    # -*- coding:utf-8 -*-
    # Author:hft
    
    import socket
    
    c = socket.socket()
    ip_port = ("192.168.50.128", 1234)
    c.connect(ip_port)
    
    #发送消息
    while True:
        sent_data = input(">>:")
        if sent_data == 'q' or sent_data == 'Q':
            break
        c.send(bytes(sent_data, encoding='utf-8'))
        res = int(str(c.recv(1024), encoding='utf-8'))
        print("字节长度为:",res,"是否收(Y/N)")
        to_recv = input(">>")
        c.send(bytes(to_recv, encoding='utf-8'))
        # recv_size = 0
        # recv_msg = b''
        # while recv_size < res:
        #     recv_data = c.recv(1024)
        #     recv_msg += recv_data
        #     recv_size += len(recv_data)
        # print(recv_size,res)
        recv_msg = c.recv(res)
        print(str(recv_msg, encoding='utf-8'))
    c.close()

    socket listen   提供可以有多少个连接

    socket 粘包  如果接收数据长度超过recv的数值,则会被下一个recv函数去接收上个未接受完的数据,所以如果数据过长,需对数据长度进行判断,如果没有接收完,需写个循环持续接收,万不能一次接收很大的数据,这样会对网络有压力

    socket 阻断   recv 和 append都有阻断效果,即没有数据或者链接过来,程序处于假死状态,一旦触发才会进行下面的代码

    socketserver

    socket在单对单链接时是没有问题的,但是网络的概念就是一对多或多对多的概念,而socket如果当下的链接未断开,则其他链接都会处于挂起状态,直到当前链接断开。socketserver提供了一个多线程的链接方式,通过它可以实现多并发的需求

    多并发   多并发即是可以多个客户端链接一个服务端,而彼此不会有影响。

    例子 ssh

    #!/user/bin/env python
    # -*- coding:utf-8 -*-
    # ssh
    
    import socketserver, subprocess
    
    class MyServer(socketserver.BaseRequestHandler):
    
        def handle(self):
            conn = self.request
            print(conn.getsockname(), "连接服务")
            while True:
    
                # 获取连接消息
                try:
                    res = conn.recv(1024)
                    send_data = res
                    p = subprocess.Popen(str(res, encoding='utf-8'), shell=True, stdout=subprocess.PIPE)
                    send_data = p.stdout.read()
                    print(type(send_data))
                    if len(res) == 0:
                        print(conn.getsockname(), '断开服务')
                        break
                    if send_data:
                        send_data = str(send_data, encoding='gbk')
                    else:
                        send_data = 'command error!'
                    print(send_data)
                    # 发送消息
                    len_data = len(bytes(send_data, encoding='utf-8'))
                    conn.sendall(bytes("%d" % len_data, encoding='utf-8'))
                    to_recv = str(conn.recv(1024), encoding='utf-8')
                    print(to_recv)
                    if to_recv == 'Y' or to_recv == 'y':
                        conn.sendall(bytes(send_data, encoding='utf-8'))
                    else:
                        print('不接收')
                        conn.sendall(bytes("OK!不接收!", encoding='utf-8'))
                except Exception:
                    print("异常!")
                    break
    
    if __name__ == '__main__':
        server = socketserver.ThreadingTCPServer(('192.168.11.86',1234), MyServer)
        server.serve_forever()

     多线程

    python中通过threading来实现多线程,通过调用threading.Thread来调用不同的线程

    threading.Thread(target=f1,args=(123,)):

        target:是调用的函数

        args:是函数的参数,是元组类型

    setDaemon:默认值为False:表示主线程等待子线程结束 才会结束

              True:表示主线程不等待子线程结束,如果主线程先结束,则程序会直接结束

    start:表示线程开始执行,前面无论定义了多少东西,都到这步才会开始执行线程。

    import time ,threading, datetime
    
    
    # def f1(i):
    #     time.sleep(1)
    #     print(i)
    #     print(datetime.datetime.now())
    #
    # print(datetime.datetime.now())
    # for j in range(10):
    #     t1 = threading.Thread(target=f1, args=(j,))
    #     t1.start()
    def f1(arg):
        time.sleep(0.5)
        print(datetime.datetime.now())
        print(arg)
    
    print(datetime.datetime.now())
    t = threading.Thread(target=f1, args=(123,))
    # f1(111)
    t.setDaemon(True)#True,表示主线程不等待此子线程执行完毕。
    t.start()#开始执行
    t.join(0.9)#表示主线程到此,等待,直到子线程执行完毕,
            #参数,表示主线程在此处至多等待N秒,然后执行下面代码
    print('end')

    作用域

    旧事重提,作用域,python作用域有几种情况

    首先块级作用域,python中没有块级作用域,即一个方法、一个代码块中,无论在哪里定义了变量,在它的下面的代码块中都可调用、修改等:

    a = 0
    while a<1:
        a += 1
        b = 1
    print(a,b)
    
    执行结果:1 1

    然后方法之间的变量是不可以直接调用,需要传参才可以进行变量的调用,需要返回值,才能进行变量修改:

    def f1():
        a = 1
    def f2():
        b = a
    f2()
    
    报错:
    NameError: name 'a' is not defined

    全局变量,这类变量可以在模块任何一处使用,不可直接去赋值,需要添加golable

    a = 1
    c = 1
    b = []
    def f1():
        a = 2
        b.append(2)
        global c
        c = 2
        print(a,b,c)
    def f2():
        print(a,b,c)
    
    f1()
    f2()

    执行结果:
      2 [2] 2   1 [2] 2

     

  • 相关阅读:
    C#学习-字段
    C#学习-静态
    C#学习-类的成员
    C#学习-面向对象语言都有类
    必须知道的 Python 专属骚技巧 25 例
    Python3读取、写入、追加写入Excel文件
    python写入excel数据xlwt模块
    Spring Boot 集成 Swagger 1
    Spring Boot 中的全局异常处理
    Java 8 开发
  • 原文地址:https://www.cnblogs.com/fukuda/p/5640210.html
Copyright © 2011-2022 走看看