• Python网络编程


      初学Python语言,今天搭建了Python环境,经朋友推荐,采用PyCharm+Anaconda搭建的环境,Anaconda是Python的开源发行版本,省去了包管理和不同Python版本的问题。由于之前熟悉网络编程,熟悉了Python基本语法后,实现了简单的网络编程。

      本篇文章包括三个部分,首先介绍了一下Socket网络编程的基础知识,然后分别从服务器端和客户端介绍了网络通信原理及代码实现。

    1. Socket基础知识

    Socket通信模型

      建立Socket连接至少需要一对套接字,其中一个运行客户端,另一个运行于服务器端。

      套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

      (1)服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。

      (2)客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。(为此,客户端套接字必须首先描述它要连接的服务器的套接字,指出服务器套接字的地址和端口号,然后就向服务器套接字提出连接请求)

      (3)连接确认:当服务器套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。(而服务器套接字继续处于监听状态,继续接收其他客户端套接字的连接请求)

    2. 服务器端

    服务器端创建Socket并绑定监听的地址和端口,并调用listen()方法开始监听端口,传入的参数指定等待连接的最大数量。

    # 服务器建立socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定监听的地址和端口
    s.bind(('127.0.0.1', 9999))
    # 开始监听端口
    s.listen(5)
    print('Waiting for connection...')

    服务器端通过while死循环不断监听来自客户端的连接请求,一旦有客户端连接,服务器的accept()方法接收请求,并创建新的线程处理请求。

    while True:
        # 接受一个新连接;
        sock, addr = s.accept()
        # 创建新线程来处理TCP连接:
        t = threading.Thread(target=tcplink, args=(sock,addr))
        t.start()

    服务器端采用多线程实现,每连接到一个客户端就创建一个新的线程,避免服务器单线程带来的阻塞问题。

    def tcplink(sock, addr):
        print('Accept new connection from %s:%s...' % addr)
        sock.send(b'Welcome!')
        while True:
            data = sock.recv(1024)
            time.sleep(1)
            if not data or data.decode('utf-8') == 'exit':
                break
            sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
        sock.close()
        print('Connection from %s:%s closed' % addr)

    连接建立后,客户端和服务器便开始通信了。程序中服务器监听到来自客户端的请求后,首先发送一条Welcome信息,然后阻塞等待客户端的数据,接收到客户端的数据后,服务器在前面加上Hello,并将消息发送给客户端。如果客户端发送"exit"串,则关闭服务器和客户端的连接。

    3. 客户端

    为测试服务器程序,我们编写了一个简单的客户端程序:

    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 建立连接:
    s.connect(('127.0.0.1', 9999))
    # 接收欢迎消息:
    print(s.recv(1024).decode('utf-8'))
    for data in [b'Michael', b'Tracy', b'Sarah']:
        # 发送数据:
        s.send(data)
        print(s.recv(1024).decode('utf-8'))
    s.send(b'exit')
    s.close()

    4. 运行结果

    服务器端

     

     客户端

     

    需要注意的是,客户端运行完成后就直接退出,而由于服务器维持着一个长连接,必须手动强制关闭程序。

    【参考资料】

    [1] 廖雪峰, TCP编程.

     

  • 相关阅读:
    git日常使用的常用命令总结
    wordpress-技术博客主题推荐
    git日常使用的常用命令总结
    wordpress-技术博客主题推荐
    Centos系统安装Python3.7
    LeetCode-----翻转二叉树
    搭建 WordPress 博客教程
    echarts 去掉网格线
    调整柱状图圆角弧度
    Echarts设置y轴值间隔 以及设置 barWidth : 30,//柱图宽度
  • 原文地址:https://www.cnblogs.com/lemonu/p/8806451.html
Copyright © 2020-2023  润新知