tornado学习 - TCPClient 实现聊天功能
之前完成了一个简单的聊天服务器,连接服务器使用的是系统自带nc
命令,接下来就是通过自己实现TCPClient
.
客户端与服务器功能大致相仿,相对与服务器只是少了转发消息环节。
首先,定义TCPClient
类,主要初始化host
、port
、stream
属性。
class SimpleTCPClient:
def __init__(self, host, port):
self._host = host
self._port = port
self._stream = None
self.EOF = b' end'
刚创建client
实例时还未与服务器连接,所以_stream
初始值为None
。EOF
设置为消息的结尾,当读到这个标识时表示一条消息输出完毕。
def get_stream(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
self._stream = tornado.iostream.IOStream(sock)
self._stream.set_close_callback(self.on_close)
获取socket
,通过tornado.iostream.IOStream
创建_stream
。
socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
中,其中第一个参数是namespace
即使用的地址,这里的AF_INET
表示使用IPv4
地址,第二个参数是style
,即socket的连接类型,这里使用的SOCK_STREAM
是流式类型基于TCP。第三个参数是protocol
指使用的协议类型,一般情况下使用0
表示系统根据情况决定。
def connect(self):
self.get_stream()
self._stream.connect((self._host, self._port), self.start)
定义连接服务器的方法,先获取_stream
然后连接服务器地址和指定端口,最后注册回调函数就是开始客户端运行的函数。
def start(self):
t1 = threading.Thread(target = self.read_msg)
t2 = threading.Thread(target = self.send_msg)
t1.daemon, t2.daemon = True, True
t1.start()
t2.start()
使用多线程同时通知收发消息。这里存在一个问题,使用多线程时,如果退出程序就必须要结束线程,否则会抛出异常,但是程序何时结束取决于用户。为了解决这个问题,将线程设置为daemon
线程,daemon
线程可以在主程序结束时自动结束。
def read_msg(self):
self._stream.read_until(self.EOF, self.show_msg)
def show_msg(self, data):
print(to_unicode(data))
self.read_msg()
接受并显示消息。当数据中读取到结束标识,调用打印消息的方法,消息打印完毕后再调用读取方法,以此保持接收消息的状态。
def send_msg(self):
while True:
data = input()
self._stream.write(bytes(data) + self.EOF)
发送消息。使用while
循环保持输入状态,当输入完成讲消息转换为byte
型,与消息结束标识拼接之后发送。
def on_close(self):
print('exit ...')
quit()
用户退出时关闭_stream
会激活这个函数。
if __name__ == '__main__':
try:
client = SimpleTCPClient('localhost', 8888)
client.connect()
tornado.ioloop.IOLoop.instance().start()
到这里TCPClient
基本完成。
之前绞尽脑汁不知道该如何解决同时保持收发信息的状态,也有想过通过多线程的方式,但是转念一想tornado
时单线程的,担心会有问题,然后就一直在纠结。
其实,编程不应该怕报错或者崩溃,遇到问题解决问题这是提高自己的途径,不应该对未知的感到担心或害怕,多尝试,大不了从头写过!
tornado学习 - TCPClient 实现聊天功能的更多相关文章
- tornado学习 - TCPServer 实现聊天功能
最近学习tornado框架,其中有很多值得学习的模块,鉴于某位学长的建议,也决定好好看看tornado.tcpserver. 关于TCP协议详细介绍可查阅wiki. 对于TCP服务器,基本的操作tor ...
- Spring 学习——基于Spring WebSocket 和STOMP实现简单的聊天功能
本篇主要讲解如何使用Spring websocket 和STOMP搭建一个简单的聊天功能项目,里面使用到的技术,如websocket和STOMP等会简单介绍,不会太深,如果对相关介绍不是很了解的,请自 ...
- 我们一起学习WCF 第九篇聊天功能
说到聊天,那么其实就是传输数据,把自己写的东西传给自己想发送的那么人.我总结一下传输常见的有三种方式 1:就是我们常见的数据库传输 2:就是文件(流)传输 3:就是socket传输 今天我们说的wcf ...
- Linux下p2p的聊天功能实现
Linux下p2p的聊天功能实现细节 Do one thing at a time, and do well. 今天闲着没事,写一个P2P的点对点的聊天功能的小程序,我觉得对网络编程初学者的学习很有用 ...
- MingQQ v1.0高仿版开源了,使用WebQQ协议实现了QQ客户端基本的聊天功能...
MingQQ v1.0高仿版开源了,使用WebQQ协议实现了QQ客户端基本的聊天功能... MingQQ目前支持的功能如下:1.支持普通方式登录.验证码方式登录.注销.保持在线.改变在线状态.2.支持 ...
- Redis实现聊天功能
在学习了Redis做为消息队列之后研究 了redis聊天的功能. 其实用关系型数据库也可以实现消息功能,自己就曾经用mysql写过一个简单的消息的功能.RDB中思路如下: ** 在实际中可以完全借助m ...
- Tornado学习
为什么用Tornado? 异步编程原理 服务器同时要对许多客户端提供服务,他的性能至关重要.而服务器端的处理流程,只要遇到了I/O操作,往往需要长时间的等待. 屏幕快照 2018-10-31 上午 ...
- 采用tcp协议和UDP协议实现简单的聊天功能
Date: 2019-06-19 Author: Sun 一. Python3输出带颜色字体 实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义 ...
- [Asp.net 开发系列之SignalR篇]专题二:使用SignalR实现酷炫端对端聊天功能
一.引言 在前一篇文章已经详细介绍了SignalR了,并且简单介绍它在Asp.net MVC 和WPF中的应用.在上篇博文介绍的都是群发消息的实现,然而,对于SignalR是为了实时聊天而生的,自然少 ...
随机推荐
- 安卓组件service
[转]http://blog.csdn.net/ithomer/article/details/7364024 一. Service简介 Service是android 系统中的四大组件之一(Acti ...
- Android控件上添加图片
项目中有一个点赞功能,点赞的小图标添加在点赞列表旁边,在xml里可以进行设置,也可以在代码中进行绘图. 下面是两种方法的设置: 1.xml里:一些控件:button.textView等等里面有个属性是 ...
- 按住ctrl键可以在新窗口打开图片
用firebug查看网页时,img标签(或background属性里面的url地址源)里面的图片源按住ctrl键可以弹出新窗口显示,并可右键另存为到本地目录
- PHP中file_exists与is_file、is_dir的区别,以及执行效率的比较
判断文件是否存在,有2个常用的PHP函数:is_file 和 file_exists, 判断文件夹是否存在,有2个常用PHP函数:is_dir 和 file_exists, 即 file_exists ...
- Brackets - 强大免费的开源跨平台Web前端开发工具IDE (HTML/CSS/Javascript代码编辑器)
Brackets 是一个免费.开源且跨平台的 HTML/CSS/JavaScript 前端 WEB 集成开发环境 (IDE工具).该项目由 Adobe 创建和维护,根据MIT许可证发布,支持 Wind ...
- html中object标签详解
定义和用法 object标签定义一个嵌入的对象.请使用此元素向您的 XHTML 页面添加多媒体.此元素允许您规定插入 HTML 文档中的对象的数据和参数,以及可用来显示和操作数据的代码. &l ...
- WPF dataGrid中的check的改变事件
关于datagrid信息: <DataGridTemplateColumn Header="备注"> <DataGridTemplateColumn.CellTe ...
- Spring MVC DispatcherServlet绑定多种URL
需要学习的内容: http://my.oschina.net/shishuifox/blog/215617 当前的处理方式,在web.xml中配置: <servlet> <servl ...
- 30万奖金!还带你奔赴加拿大相约KDD!?阿里聚安全算法挑战赛带你飞起!
KDD(Knowledge Discovery and Data Mining,知识发现与数据挖掘)会议,作为数据挖掘届的顶会,一直是算法爱好者心中的圣地麦加. 想去?有点难. 给你奖金和差旅赞助 ...
- SQL SERVER分区具体例子详解
在日常工作中,我们会遇到以下的情况,一个表每日数万级的增长,而查询的数据通常是在本月或今年,以前的数据偶尔会用到,但查询和插入的效率越来越慢,用数据库分区会有助于解决这个问题.关于分区的理论知识网上很 ...