最近学习了一下另一个网络库:libuv,一个文档少,开始令人一头雾水,然后还是很好用的一个库。当然学习该库最重要的原则就是------去看“uv.h”头文件,里面有你想知道的一切。
1. 改了uv_book中的一个例子代码如下:
a.下面的是client
#include
#include
#include
#include
#include
#include
uv_loop_t *loop;
uv_tcp_t *client;
void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
void do_read();
void do_write();
void echo_write(uv_write_t *req, int status);
void echo_read(uv_stream_t *client_, ssize_t nread, const uv_buf_t* buf) ;
void on_connection(uv_connect_t* req, int status);
void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
*buf = uv_buf_init((char*) malloc(suggested_size), suggested_size);
}
void do_read()
{
int r = uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read);
if(r<0)
{
fprintf(stderr, "Read error %s\n", uv_err_name(r));
uv_close((uv_handle_t*)client, NULL);
}
}
void do_write()
{
uv_write_t *req_write = (uv_write_t *) malloc(sizeof(uv_write_t));
char *line = (char*)malloc(1024*sizeof(char));
memset(line, 0, 1024);
int len = 0;
while (gets(line))
{
for(; len<1024; len++)
{
if(line[len] == 0)
break;
}
break;
}
uv_buf_t *buf = (uv_buf_t*)malloc(sizeof(uv_buf_t));
uv_buf_init(line, len+1);
buf->base = line;
buf->len = len+1;
req_write->data = (void*) buf->base;
int r = uv_write(req_write, (uv_stream_t*)client, buf, 1, echo_write);
if(r<0)
{
fprintf(stderr, "write error %s\n", uv_err_name(r));
uv_close((uv_handle_t*)client, NULL);
}
}
void echo_write(uv_write_t *req, int status)
{
if (status < 0) {
fprintf(stderr, "Write error %s\n", uv_err_name(status));
}
char *base = (char*) req->data;
free(base);
free(req);
do_write();
}
void echo_read(uv_stream_t *client_, ssize_t nread, const uv_buf_t* buf)
{
if (nread < 0) {
if (nread == UV_EOF){
fprintf(stderr, "UV_EOF....\n");
}else{
fprintf(stderr, "Read error %s : %s\n", uv_err_name(nread), uv_strerror(nread));
}
uv_close((uv_handle_t*) client_, NULL);
return;
}else{
printf("%s\n", buf->base);
}
do_read();
}
void on_connection(uv_connect_t* req, int status) {
if (status < 0) {
// error!
fprintf(stderr, "connect error %s : %s\n", uv_err_name(status), uv_strerror(status));
return;
}
free(req);
do_read();
do_write();
}
int main() {
loop = uv_default_loop();
client = (uv_tcp_t *)malloc(sizeof(uv_tcp_t));
uv_tcp_init(loop, client);
struct sockaddr_in bind_addr;
uv_ip4_addr("127.0.0.1", 7000, &bind_addr);
uv_connect_t *req = (uv_connect_t *)malloc(sizeof(uv_connect_t));
int r = uv_tcp_connect(req, client, (const sockaddr*)&bind_addr, on_connection);
if (r) {
fprintf(stderr, "connect error %s\n", uv_err_name(r));
return 1;
}
return uv_run(loop, UV_RUN_DEFAULT);
}
b.下面的是server
#include
#include
#include
#include
uv_loop_t *loop;
void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
*buf = uv_buf_init((char*) malloc(suggested_size), suggested_size);
}
void echo_write(uv_write_t *req, int status) {
if (status < 0) {
fprintf(stderr, "Write error %s\n", uv_err_name(status));
}
char *base = (char*) req->data;
free(base);
free(req);
}
void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t* buf) {
if (nread < 0) {
if (nread == UV_EOF){
fprintf(stderr, "UV_EOF....\n");
}else{
fprintf(stderr, "Read error %s : %s\n", uv_err_name(nread), uv_strerror(nread));
}
uv_close((uv_handle_t*) client, NULL);
return;
}
printf("%s\n", buf->base);
uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t)); //alloc write watcher
req->data = (void*) buf->base;
uv_write(req, client, buf, 1, echo_write);
}
void on_new_connection(uv_stream_t *server, int status) {
printf("enter on_new_connection...\n");
if (status == -1) {
// error!
return;
}
uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
uv_tcp_init(loop, client);
if (uv_accept(server, (uv_stream_t*) client) == 0) {
int r = uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read);
if(r<0)
{
fprintf(stderr, "Read error %s\n", uv_err_name(r));
uv_close((uv_handle_t*)client, NULL);
}
}
else {
uv_close((uv_handle_t*) client, NULL);
}
}
int main() {
loop = uv_default_loop();
uv_tcp_t server;
uv_tcp_init(loop, &server);
struct sockaddr_in bind_addr;
uv_ip4_addr("0.0.0.0", 7000, &bind_addr);
uv_tcp_bind(&server, (const sockaddr*)&bind_addr, 0); //0--ipv4; 1--ipv6
int r = uv_listen((uv_stream_t*) &server, 128, on_new_connection);
if (r) {
fprintf(stderr, "Listen error %s\n", uv_err_name(r));
return 1;
}
return uv_run(loop, UV_RUN_DEFAULT);
}
2. 用的libuv的版本是libuv-v1.9.1,编译程序完毕后,执行的时候出现如下错误:
------------error while loading shared libraries: libuv.so.1: cannot open shared object file : No such file---------------
用 “ldd” 查看需要的库时,的确 “libuv.so.1” 说未被发现,可是查看 “/usr/local/bin” 明明是存在该库的。
------------------------------------------------------------------解决办法----------------------------------------------------------------
3. <方法1> 执行 “ldconfig” 命令,该命令可让动态链接库为系统所共享。发生错误的原因就是安装libuv库后,没有更新系统链接库名字列表,导致系统找不到该库。
<方法2> 编译的时候指定动态链接库链接路径, 用gcc编译时,添加 “-Wl,-rpath=动态库路径”即可。