Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1292627
  • 博文数量: 79
  • 博客积分: 1959
  • 博客等级: 上尉
  • 技术积分: 2719
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-19 12:07
个人简介

樽中酒不空

文章分类

全部博文(79)

文章存档

2024年(3)

2020年(4)

2019年(1)

2017年(2)

2016年(2)

2015年(7)

2014年(11)

2013年(13)

2012年(18)

2011年(2)

2010年(16)

分类: C/C++

2014-05-27 14:14:09

libuv是一个简洁而又强大的网络库,用来做简单的IM Server等非常适用。
开始可以根据附带的test程序学习。不过里面有一些小地方要稍加注意,这里主要讲read_cb时对方断开的处理:

在blackhole-server.c有如下语句:

static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
  conn_rec* conn;
  int r;

  if (nread >= 0)
    return;

  ASSERT(nread == UV_EOF);
  conn = container_of(stream, conn_rec, handle);
  r = uv_shutdown(&conn->shutdown_req, stream, shutdown_cb);
  ASSERT(r == 0);
}

代码很简单,nread<0时shutdown socket。不过这时容易引起异常:当对方主动断开,或网络故障断开时,libuv会出一个异常,大致意思是,此处不应该用shutdown,而是直接close。
此处可以参考test-tcp-write-to-half-open-connection.c:


static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
  if (nread < 0) {
    fprintf(stderr, "read_cb error: %s\n", uv_err_name(nread));
    ASSERT(nread == UV_ECONNRESET || nread == UV_EOF);


    uv_close((uv_handle_t*)&tcp_server, NULL);
    uv_close((uv_handle_t*)&tcp_peer, NULL);
  }
  read_cb_called++;
}

在其他的test里也是用的close,比如test-tcp-writealot.c,test-tcp-write-to-half-open-connection.c,benchmark-pound.c等 等。

好象只有blackhole-server.c这里面用shutdown了,主要是和演示的功能有关。
有朋友问libuv怎么用,随手就把blackhole-server这个例子
拿出来。不过使用中发现经常有异常,跟踪一下发现了这个问题。看代码还是要更细心一些,暂记。

阅读(10829) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~

jedihy2015-02-06 11:09:19

我觉得这里不对,shutdown是一个方向的关闭,文档上已经说了,对方主动断开我当然也只用shutdown和uv_read_stop

sxcong2014-06-13 14:39:44

xsoda:我觉得该关闭连接的地方都应该用
int r = uv_shutdown(req, stream, callback);
if (r) {
   free(req);
   uv_close(handle, callback);
}
然后在uv_shutdown的callback中再调用uv_close;

理论上应该这样,一般主动断开socket时uv_shutdown没问题。
不过在对方先断开socket时,本地执行uv_shutdown会异常,跟踪代码能发现:
src\unix\stream.c: 
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
  assert((stream->type == UV_TCP || stream->type == UV_NAMED_PIPE) &&
         "uv_shutdown (unix) only supports uv_handle_t right now");

  if (!(stream->flags & UV_STRE

回复 | 举报

xsoda2014-06-13 11:20:58

我觉得该关闭连接的地方都应该用
int r = uv_shutdown(req, stream, callback);
if (r) {
   free(req);
   uv_close(handle, callback);
}
然后在uv_shutdown的callback中再调用uv_close;

tsla1002014-05-29 19:29:16

学习了