標籤:程式 nec occurs 平台 receive _id 接受 not forever
代碼:
1 # socket test with ForkingMixIn class 2 3 import os 4 import socket 5 import SocketServer 6 import threading 7 # from multiprocessing import Process 8 9 SERVER_HOST = "localhost"10 SERVER_PORT = 0 # indicat to use dyminic port11 BUF_SIZE = 102412 ECHO_MSG = "Hello echo server"13 14 15 class ForkingClient():16 """a client to use forking server """17 def __init__(self, ip, port):18 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)19 self.sock.connect((ip, port))20 21 def run(self):22 """ client send infor to server """23 # get current client‘s ip 24 current_process_id = os.getpid()25 print "PID %s sending echo messages to server: %s" % 26 (current_process_id, ECHO_MSG)27 # use sock.send() to get length28 sent_data_length = self.sock.send(ECHO_MSG)29 print "%s characters sent so far..." % sent_data_length30 31 # get the server response32 s_response = self.sock.recv(BUF_SIZE)33 # disp the server response, split s_response34 print "PID %s received: %s" % ( current_process_id, s_response[5:] )35 36 def clientshutdown(self):37 self.sock.close()38 39 # def server‘s handle mthd40 class ForkingServerRequestHandler(SocketServer.BaseRequestHandler):41 def handle(self):42 # get echo from client, notice "request.recv()"43 data = self.request.recv(BUF_SIZE)44 current_process_id = os.getpid()45 s_response = ‘%s: %s‘ % ( current_process_id, data)46 # send echo back to client47 print "Server sending back [current_process_id: data] %s" % 48 s_response49 # use .request.send() mthd50 self.request.send(s_response)51 # use return52 return53 54 class ForkingServer(SocketServer.ForkingMixIn, SocketServer.TCPServer):55 """ just inherit everything from parents """56 pass57 58 def main():59 # build the server like TCPServer initiate 60 server = ForkingServer( (SERVER_HOST, SERVER_PORT), ForkingServerRequestHandler)61 62 ip, port = server.server_address # get server‘s ip and port63 # serve_forever Handle requests until an explicit shutdown() request. 64 server_thread = threading.Thread(target=server.serve_forever)65 server_thread.setDaemon(True)66 67 # server start68 server_thread.start()69 #server_thread.join()70 print "Server loop runing PID: %s" % os.getpid()71 72 # build client and start73 74 client1 = ForkingClient(ip, port) # use server‘s ip and port75 client1.run()76 77 client2 = ForkingClient(ip, port)78 client2.run()79 80 # clean81 server.shutdown()82 client1.clientshutdown()83 client2.clientshutdown()84 server.socket.close()85 86 if __name__ == ‘__main__‘:87 main()
程式注意點如下:
1. 初次在Windows上運行時報錯如下, 在協助文檔查詢到os.fork只能運行在unix平台:
報錯:
File "C:\Python27\lib\SocketServer.py", line 556, in process_request
pid = os.fork() AttributeError: ‘module‘ object has no attribute ‘fork‘
os.fork()說明:
-
Fork a child process. Return 0 in the child and the child’s process id in the parent. If an error occurs OSError is raised.
Note that some platforms including FreeBSD <= 6.3, Cygwin and OS/2 EMX have known issues when using fork() from a thread.
Availability: Unix.
2. 在main塊執行完SERVER和CLIENT的發送及接受後,SERVER執行了shutdown()後又執行socket.close(),為什麼要這麼做?
shutdown()關閉讀寫的串連並發送Fin/EOF 訊號給所有的節點,而不管有多少進程串連在SERVER上,但是它不釋放串連,所以再調用close()來釋放
Python網路編程(一)