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

import socket
 import os
 from time import strftimehost = ''
 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炸弹。不断的产生子进程。