一、Socket应用:
服务器:
sockt -->bind-->listen-->accept-->send-->recv-->close
客户端:
socket-->bind-->connect-->send-->recv-->close
#filename:simple_server.py
#encoding=utf-8
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #生成socket对象
# 地址族 套接字类型 协议默认为0
host = socket.gethostname() #获取主机名称
port = 1234 #设置端口号
s.bind((host,port))#绑定socket地址
s.listen(10) #开始监听
while True:
c,addr = s.accept() #接受一个连接
print('Get connection from',addr)
c.send(b"this is a simple server")#发送数据
c.close()
使用SocketServer模块
#filename: TCP_socket_server.py
from socketserver import TCPServer,StreamRequestHandler
class MyHandler(StreamRequestHandler):
def handler(self):
addr = self.request.getpeername()
print('Get connection from', addr)
self.wfile.write(b'This is a tcp socket server')
host = '192.168.43.167'
port = 1234
server = TCPServer((host, port), MyHandler)
server.serve_forever()
客户端构建:
#encoding=utf-8
import socket
s=socket.socket()
server = socket.gethostname()
port = 1234
s.connect((server,port))
print (s.recv(1024))
s.close()
二、异步通信方式:
1.使用Fork(进程)方式:
FrokingMixIn 每次接受到新的连接时,创建新的进程。
2.使用线程方式:
ThreadingMixIn 利用多线程实现异步
3.使用异步IO方式:
select:
#filename; select_ex.py
import socket, select
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)
inputs = [s]
while True:
rs, ws, es =select.select(inputs, [], [])
for r in rs:
if r is s:
c, addr = s.accept()
print('Get connection from', addr)
inputs.append(c)
else:
try:
data = r.recv(1024)
disconnected = not data
except socket.error:
disconnected = True
if disconnected:
print(r.getpeername(), 'disconnected')
inputs.remove(r)
else:
print(data)
4.使用asyncore模块:
#filename: asyncore_ex.py import asyncore, socket class HttpClient(asyncore.dispatcher): def __init__(self,host, path): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.connect((host, 80)) self.buffer = 'GET %s HTTP/1.0\r\n\r\n' % path def handle_connect(self): pass def handle_close(self): self.close() def handle_write(self): sent = self.send(self.buffer) self.buffer = self.buffer[sent:] def writable(self): return (len(self.buffer)>0) if __name__ =='__main__': c = HttpClient('www.baidu.com','/') asyncore.loop()
Twisted网络框架
#filename : twisted_server_1.py from twisted.internet import reactor from twisted.internet.protocol import Protocol, Factory class SimpleServer(Protocol): def connectionMade(self): print('Get connection from',self.transport.client) def connectionLost(self, reason): print(self.transport.client, 'disconnected') def dataReceived(self): print(data) factory = Factory() factory.protocol = SimpleServer port =1234 reactor.listenTCP(port, factory) reactor.run()
twisted.protocols.basic中包含LineReceiver 实现整行接收处理
服务器端发送给客户端信息:
Protocol.transport.write()
限制接入的客户端数量
def connectionMade(self): print('Get connection from', self.transport.client) self.factory.numProtocols = self.factory.numProtocols+1 if self.factory.numProtocols >5: self.transport.write("too many connections, try later") self.transport.loseconnection()
练习:简单的聊天程序
server.py
import socket host = socket.gethostname() port = 12345 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind((host,port)) s.listen(1) sock,addr = s.accept() print('Connection built') info = sock.recv(1024).decode() while info != 'exit': print('Client:'+info) send_mes = input() sock.send(send_mes.encode()) if send_mes =='exit': break info = sock.recv(1024).decode() sock.close() s.close()client.py
import socket s= socket.socket() host = socket.gethostname() port = 12345 s.connect((host,port)) print('Linked') info = '' while info != 'exit': print('Server:'+info) send_mes=input() s.send(send_mes.encode()) if send_mes =='exit': break info = s.recv(1024).decode() s.close()