#master-worker模型:
#coding:utf-8
import os
import sys
import socket
import time
import traceback
import errno
import signal
class Worker(object):
def __init__(self, sock):
self.sock = sock
def accept(self):
client, addr = self.sock.accept()
client.setblocking(True)
self.handle(client, addr)
def init_process(self):
self.sock.setblocking(False)
while True:
try:
time.sleep(1)
self.accept()
continue
except Exception as e:
msg = traceback.format_exc()
with open("sub_"+str(os.getpid())+".txt","a") as f:
f.write(msg+"\n")
if hasattr(e, "errno"):
if e.errno not in (errno.EAGAIN, errno.ECONNABORTED, errno.EWOULDBLOCK):
msg = traceback.format_exc()
else:
raise
def handle(self, client, addr):
data = client.recv(1024)
pid = os.getpid()
data += str(pid)
# print("receive:{} pid:{}".format(data, pid))
client.send("back:"+data)
client.close()
class Server(object):
def __init__(self):
self.port = ("127.0.0.1", 8004)
self.sock = socket.socket()
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(self.port)
self.sock.setblocking(False)
self.sock.listen(5)
self.WORKERS = {}
def run(self):
self.init_signals()
for i in range(2):
self.spawn_worker()
print(i)
# self.spawn_worker()
for k in self.WORKERS:
print(k, self.WORKERS[k])
while True:
import time
time.sleep(3)
try:
pid, status = os.waitpid(-1, os.WNOHANG)
print("kill pid: {}, status: {}".format(pid, status))
except os.error:
print("error")
def init_signals(self):
signal.signal(signal.SIGTTIN, self.incr_one)
signal.signal(signal.SIGTTOU, self.decr_one)
def incr_one(self, signo, frame):
self.spawn_worker()
for k in self.WORKERS:
print(k, self.WORKERS[k])
def decr_one(self, signo, frame):
for k in self.WORKERS:
os.kill(k, signal.SIGKILL)
break
def spawn_worker(self):
worker = Worker(self.sock)
pid = os.fork()
if pid != 0:
worker.pid = pid
self.WORKERS[pid] = worker
return pid
worker.pid = os.getpid()
worker.init_process()
sys.exit(0)
if __name__ == "__main__":
server = Server()
server.run()
=======================================================================
epoll模型:
server:
#-*- coding:utf8 -*-
import socket
import select
import os
address = "0.0.0.0"
port = 10001
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
def main():
global address,port,sock
epoll = select.epoll()
#获取创建好的sock的文件描述符
fd = sock.fileno()
sock.bind((address,port))
sock_dict = {}
sock_dict[fd] = sock
#对该sock进行注册
epoll.register(fd,select.EPOLLIN)
sock.listen(5)
while True:
events = epoll.poll(1)
for fileno,event in events:
#获取到的文件描述符和sock的相同就说明是一个新的连接
if fileno == fd:
(client,address) = sock.accept()
print address
client.setblocking(0)
#将新的连接进行注册,用来接收消息
epoll.register(client.fileno(),select.EPOLLIN)
sock_dict[client.fileno()] = client
elif event & select.EPOLLIN:
print "fileno:",fileno
data = sock_dict[fileno].recv(128)
if data == '你好':
print "Data:",data.decode('UTF-8')
sock_dict[fileno].send("你好")
elif len(data) == 0:
print "线路%d已下线"%fileno
epoll.unregister(fileno)
else:
print "Data:",data
if __name__ == '__main__':
main()
client:
#coding: UTF-8
import socket
import select
address = "127.0.0.1"
port = 10001
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
def main():
global address,port,sock
sock.connect((address,port))
epoll = select.epoll()
fd = sock.fileno()
#这里的epoll注册只是用来异步接收服务端发过来的消息
epoll.register(fd,select.EPOLLIN)
while True:
events = epoll.poll(1)
for fileno,event in events:
if fileno == fd:
if event & select.EPOLLIN:
data = sock.recv(128)
print data
data = raw_input(">")
if data == 'q':
break
elif data == '':
print "不能发送空消息"
continue
sock.send(data)
sock.close()
main()