1.参考文档、博客链接
(1)tornado参考手册,这个手册说的是python2.x版本的tornado编程,拿过来参考参考
http://demo.pythoner.com/itt2zh/
(2)tornado的socket编程参考,
1.环境
python3x + tornado +socket
2.代码
(1)创建文件夹
01.py
from tornado.iostream import IOStream, StreamClosedError
from tornado.tcpserver import TCPServer
from tornado.web import RequestHandler # 导入RequestHandler类
from tornado.web import Application # 导入Tornado的Application类
from tornado.options import define, options
from tornado import ioloop
import traceback
import os.path
'''
下面的是socket_sever
'''
class Connecter:
clients = set() #存放连接的客户端
async def init(self, stream: IOStream, address: tuple):
'''
:param stream: socket的数据流通道
:param address: 客户端的ip 和 id
:return:
'''
self.stream, self.address = stream, address
self.clients.add(self)
print("{address} 上线!".format(address=address))
self.stream.set_close_callback(self.onClose) # 客户端离线的时候会被调
await self.receive() # 接受消息
async def receive(self):
'''
接受消息
:return:
'''
while not self.stream.closed(): # 此处改为IOStream没有关闭就继续循环
try:
data = await self.stream.read_bytes(num_bytes=1024, partial=True)
SocketData.data=data.decode('utf8')
print(data)
except StreamClosedError as e:
break
except:
traceback.print_exc() # 把其他错误打印出来
def send(self, data):
'''
发送消息
:param data:消息内容
:return:
'''
self.stream.write(bytes(data.encode('utf8')))
def onClose(self):
'''
客户端离线
:return:
'''
print("{address} 离线!".format(address=self.address))
self.clients.remove(self) # 在clients内删掉该客户端
class SocketServer(TCPServer): # 需要继承TCPServer这个类
'''
构建一个SocketServer类
'''
async def handle_stream(self, stream: IOStream, address: tuple): # 实现类里面的handle_stream方法
await Connecter().init(stream, address) # 每次有客户端连入都实例化一个Connecter类
SocketData.ip=SocketData.ip.__add__(address)
class SocketData:
data = ''
ip = ''
'''
下面的是web服务器的实现
'''
class IndexHandler(RequestHandler): # 继承RequestHandler类
def get(self): # 实现GET方法,GET请求会执行这个方法
self.render('index.html')
class PoemPageHandler(RequestHandler):
def post(self): # 实现POST方法,POST请求会执行这个方法
msg = self.get_argument("msg") # 得到post请求中的msg的值
ip = self.get_argument('ip') # 得到要发送的ip
#cc = self.get_argument('client')
c = Connecter() # 实例化Connecter类
# cc = c.clients
# print("cc= " + format(cc))
print(SocketData.ip)
counter = 0 # 记录发送到客户端的个数
for client in c.clients: # type:Connecter
if client.address[0] == ip: # 根据ip发送
print (client.address[0])
SocketData.ip = client.address
client.send(msg) # 发送消息
counter += 1 # 计数加1
self.write("{'send_counter':" + str(counter) + "}")
self.render('poem.html', msg=SocketData.data, ip=SocketData.ip)
def webServerApp(): # 构造出webApp
return Application([
(r'/', IndexHandler), (r'/poem', PoemPageHandler)],
template_path = os.path.join(os.path.dirname(__file__), "templates"))
'''
下面的是主要函数
'''
#这里用define定义端口,可以方便使用命令行参数的形式修改端口
define("socketPort", 8888, type=int) # socket默认使用8888端口
define("webPort", 8080, type=int) # web默认使用8080端口
def main():
socket_server = SocketServer()
socket_server.listen(options.socketPort, '0.0.0.0')
print("socket服务器启动,端口:{port}".format(port=options.socketPort))
app = webServerApp()
app.listen(options.webPort, '0.0.0.0')
print("web服务器启动,端口:{port}".format(port=options.webPort))
try: # 此处修复不能使用一次Ctrl+C结束程序
print("按 Ctrl+C 可结束程序!")
ioloop.IOLoop.current().start()
except KeyboardInterrupt:
ioloop.IOLoop.current().stop()
print("程序已经结束!")
if __name__ == '__main__':
main()
02.py
import socket
p = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
p.connect(('192.168.144.128', 8888))
while 1:
msg = input('please input')
p.send(msg.encode('utf-8'))
if msg == '1':
break
p.close()
03.py
import socket
obj = socket.socket()
obj.connect(("127.0.0.1",8888))
while True:
ret = str(obj.recv(1024),encoding="utf-8")
print(ret)
index.html
<!DOCTYPE html>
<html>
<head><title>Poem Maker Pro</title></head>
<body>
<h1>Enter terms below.</h1>
<form method="post" action="/poem">
<p>Plural noun<br><input type="text" name="msg"></p>
<p>Singular noun<br><input type="text" name="ip"></p>
<p>Verb (past tense)<br><input type="text" name="client"></p>
<p>Noun<br><input type="text" name="noun3"></p>
<input type="submit">
</form>
</body>
</html>
poem.html
<!DOCTYPE html>
<html>
<head><title>Poem Maker Pro</title></head>
<body>
<h1>Your poem</h1>
<p>msg={{msg}} and
{% for i in ip %}
ip = {{ip}}
{% end %}</p>
</body>
</html>