一、本人设想的TCP服务器有如下特性:

1.启动服务,一直监听端口。

2.有新连接(客户端)就通知用户。并把连接接收到的数据回调给用户。

3.客户端连接上后用户可在任意时间发送数据给它。

4.客户端断开时关闭或用户可手动关掉。

以上操作都可以不同线程在完成。

二、使用libuv遇到的问题

由于对libuv不熟悉+其文档,调用其函数时吃了不少苦头。

1.libuv的特性

libuv是基于event驱动的,当调用uv_run后就会一直启动event循环,阻塞其线程(event loop thread)直到没有事件了uv_run返回。除了uv_async_send函数外,其他函数都是非线程安全的。即其他函数只能在event loop thread里调用,在其他线程调用libuv不保证其正确性。

libuv处处回调,多数有回调的函数都是直到回调函数被触发时才算调用完成,而非该函数返回就算调用完成。

2.遇到的问题

libuv的这点特性对于我想通过多线程调用tcp sever中的不同操作是一大麻烦事。

2.1.我在另一线程里调用了uv_write发送数据,结果总提示Assertion failed: handle->write_queue_size >= req->queued_bytes, file src/win/tcp.c

最后在google group( https://groups.google.com/forum/#!msg/libuv/iHzv3x-VOr4/KzhJymI6lRkJ )中找到方法:

内部开辟一线程用于发送数据。用户调用发送函数时把数据压入队列,发送线程从队列中循环取数据,然后调用uv_async_send触发真正的发送数据函数。数据参数可以通过uv_handle_t.data传输。可用uv_sem_wait/ uv_sem_post来控制数据发送先后。

2.2.对于想要关闭一个客户端,可使用uv_close关闭其所关联的uv_handle_t,然后把客户端参数从客户端队列中删除。

但是libuv这种处处回调的函数,调用uv_close返回后并不意味着真正close成功了,此时若把客户端删除,则会调用客户端的析构函数,客户端的所有变量地址都是未知的了。因为uv_close后对客户端继续操作,所以访问这些未知变量地址会出错。真正close成功是在uv_close_cb被触发时。

所以想要delete掉一个客户端,得调用uv_close,然后在uv_close_cb等待并判断是哪个客户端,再把客户端删除。

2.3 同uv_close, uv_tcp_connect也一样,不能uv_tcp_connect就想发送数据,得等其回调函数触发后才能进行发送数据操作。uv_write也一样。

总结:libuv好不好,会用才好,不会用坑一大堆。

三、传输规则定义

网络传输中不能只接受裸流,必须对数据进行卦包与拆包,一来可防止数据被篡改与丢失,二来方便数据解析。

CSDN上对网络数据如何定义有讨论过:http://bbs.csdn.net/topics/380167545

本人定义的包结构如下:

// 一个数据包的内存结构

//增加包头与包尾数据,用于检测包的完整性。检验值用于检测包的完全性。

//|-----head----|--------------------------pack header-------------------|--------------------pack data------------|-----tail----|

//|--包头1字节--|--[version][head][tail][check][type][datalen][reserve]--|--datalen长度的内存数据(根据type去解析)--|--包尾1字节--|

#pragma pack(1)//将当前字节对齐值设为1

#define NET_PACKAGE_VERSION 0x01

typedef struct _NetPacket{//传输自定义数据包头结构

int32_t version; //封包的版本号,不同版本包的定义可能不同 :0-3

unsigned char header; //包头-可自定义,例如0x02 :4

unsigned char tail; //包尾-可自定义,例如0x03 :5

unsigned char check[16];//pack data校验值-16字节的md5二进制数据 :6-21

int32_t type; //包数据的类型 :22-25

int32_t datalen; //包数据的内容长度-不包括此包结构和包头尾 :26-29

int32_t reserve; //包数据保留字段-暂时不使用 :30-33

}NetPacket;

#define NET_PACKAGE_HEADLEN sizeof(NetPacket)//包头长度,为固定大小34字节

同时进行了封包与折包工作,详见packet.h

——————————————————————————————————————————————————————————————————————

代码已上传到git: https://github.com/wqvbjhc/libuv_tcp

客户端的测试例子有缺陷,但服务器完全正常。

服务器可以接收上百路连接。

转载于:https://www.cnblogs.com/wqvbjhc/p/3758141.html

基于libuv的TCP设计(二)相关推荐

  1. (原创)基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示

    在(原创基于ZedBoard的Webcam设计(一):Zedboard上的USB摄像头(V4L2接口)的图片采集中,我们完成了ZedBoard上USB摄像头的单幅图片采集,采集到的图片是存储在文件系统 ...

  2. 基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示

    在(原创基于ZedBoard的Webcam设计(一):Zedboard上的USB摄像头(V4L2接口)的图片采集中,我们完成了ZedBoard上USB摄像头的单幅图片采集,采集到的图片是存储在文件系统 ...

  3. PHP设计BBS,基于mysql的bbs设计二_PHP教程

    3.数据库设计 关键还是mysql的效率问题,合理分配mysql的内存,特别是table cache的 大小.另外,当系统突然掉电呢?mysql是否robust? table的名字设计,采用一位前缀表 ...

  4. 【正点原子FPGA连载】 第三十二章基于lwip的TCP服务器性能测试实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

    第三十二章基于lwip的TCP服务器性能测试实验 上一章的lwip Echo Server实验让我们对lwip有一个基本的了解,而Echo Server是基于TCP协议的.TCP协议是为了在不可靠的互 ...

  5. Thinking in AJAX(二) —— 基于AJAX的WEB设计

    Thinking in AJAX(二) -- 基于AJAX的WEB设计 一.AJAX最值得称赞的是异步交互,而不是无刷新 很多人都看好AJAX无刷新的技术,以至于认同AJAX就是用来做无刷新的.这个认 ...

  6. 基于 MongoDB 动态字段设计的探索 (二) 聚合操作

    业务需求及设计见前文:基于 MongoDB 动态字段设计的探索 根据专业计算各科平均分 (总分.最高分.最低分) public Object avg(String major){Aggregation ...

  7. 架构风格与基于网络的软件架构设计

    原文链接 https://blog.csdn.net/on_1y/article/details/60358117 架构风格与基于网络的软件架构设计 如今许多服务都采用了 RESTful API, 而 ...

  8. (转)架构风格与基于网络的软件架构设计(介绍REST)

    随着软件水平在国内的发展,中国程序员的水平也逐渐的在提高,从当年英雄式,到后来的软件作坊,现在越来越多的人开始关注软件架构设计,软件架构师培训也越来越火了,,甚至也有国人自己编著软件架构设计方面的书籍 ...

  9. 基于单片机温湿度报警器设计(wifi版)

    本文章详细word资料参考地址如下:基于单片机温湿度报警器设计(wifi版).rar_STC-B温度报警器-硬件开发文档类资源-CSDN下载https://download.csdn.net/down ...

最新文章

  1. Leetcode: Palindrome Numbers
  2. mac改终端前面的计算机名
  3. vc6 前进后退 番茄_openMP 使用 VC6+Intel Compiler 9.1 (来自网络)
  4. boost::units::conversion_factor相关的测试程序
  5. 工作218:页面样式调整
  6. 从零开始学PowerShell(5)自定义格式化信息
  7. VS2010中编写x64汇编的具体方法
  8. [转]Linux内核的文件预读(readahead)
  9. Linux之route命令
  10. java线程池原理简答_面试官让我讲讲Java线程池的实现原理,我笑了...
  11. macbook交叉编译linux,mac交叉编译到Linux报错
  12. 使用urllib,re,queue,threading,bs4,requests多线程队列爬取图片到本地保存
  13. struts2和hibernate的简单新闻发布系统_点赞!北斗卫星导航系统28nm工艺芯片已量产,全球范围定位精度优于10米...
  14. 城镇化进程中的粮食生产问题
  15. 30 行代码实现,支付宝蚂蚁森林自动收能量!
  16. 开发团队分配管理软件
  17. 在office2010的ppt中加入音乐
  18. 软件产品确认测试包括哪些方面
  19. window11 定时关机脚本
  20. 城市防疫黑科技,联诚发5G多功能智慧杆显身手

热门文章

  1. git如何查看和切换账号
  2. 查询mysql数据库中所有表名
  3. Android开发笔记(二十五)assets目录下的文件读取
  4. Redlock 算法:Redis 实现分布式锁(译)
  5. 简述关系型数据库和非关系型数据库
  6. iOS获取、写入系统相册图片
  7. DBCC DBREINDEX重建索引提高SQL Server性能
  8. LinkedIn会成为下一个诺基亚吗?
  9. Win10,Win7,WinServer2012,WinServer2008内存最大支持
  10. 人人都是产品经理 笔记