函数式编程:python3利用socket模块模拟TCP通信-多进程多客户端连接

模拟TCP通信过程,此例多次连接,采用的方式是多进程的方式。实现的功能是,多客户端连接服务器21567端口,采用的连接方式是TCP,发送数据给与服务端,服务端打印出数据,然后反馈(【当前时间】发送数据)给回各客户端

import socket
import os
from time import strftime

host = ''
port = 21567
addr = (host, port)
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(2)

while True:                                                          ##外循环控件服务端等待接收客户端连接
    cli_sock, cli_addr = s.accept()
    pid = os.fork()                                                 ##使用os模块的fork功能,复制进程。
    if pid:                                                              ##判断,如果pid不为0,也就等于是主进程
        cli_sock.close()                                          ##主进程只负责服务端的连接,关闭客户端的连接
        while True:                                                 ##加一个循环控制主进程进行僵尸进程的操作
            result = os.waitpid(-1, 1)[0]                   ##此处的-1,代表沿用C语言的格式,1表示进程不挂起,因为os.waitpid返回的结                                                                                果是一个元组,元组第一项就是进程的pid。所以取下表0
            if result == 0:                                         ##判断,如果子进程pid的0,也就代表是僵尸进程(退出),不为0是正常运行的                                                                                子进程
                break
    else:                                                              ##如果pid不为0,等于是子进程
        s.close()                                                    ##子进程负责客户端的全部操作。但不负责服务端的操作,所以关闭服务端。
        while True:                                                ##内循环负责控制服务端的数据接收和发送的工作
            rdata = cli_sock.recv(1024)
            rdata = rdata.decode('utf8')
            if rdata.strip() == 'quit':
                break
            print(rdata.strip())
            sdata = '[%s] %s' % (strftime('%H:%S:%M'), rdata)
            cli_sock.send(sdata.encode('utf8'))
        cli_sock.close()
        exit()                                                          ##这里很重要。此处是归属到子进程的工作的。如果不写退出。那么子进程完成                                                                                工作后,会重新进入循环,子进程还会产生子进程,从而发生fork炸弹。
s.close()


此例为多次连接,函数式编程,程序的执行是从上到下执行的。比较好理解。总体来说,服务端等待接收数据,但客户端连接进来的时候,生成一份子进程。进行判断,如果是主进程,那么关闭客户端连接服务。如果是子进程。关闭服务端连接服务。等待客户端连接的事情交给主进程。具体处理其他工作交给子进程。由于多进程会产生僵尸进程,所以把处理僵尸进程的工作,交给主进程。最后注意,子进程是在外循环内的。如果子进程完成工作后没有退出。那么循环再次开始的时候,会产生fork炸弹。不断的产生子进程。

发布了73 篇原创文章 · 获赞 4 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_27592485/article/details/100767398
今日推荐