libuv 简单回显客户端
libuv simple echo client
我正在尝试为以下示例代码使用 unix 管道开发一个简单的 echo 客户端:https://github.com/nikhilm/uvbook/blob/master/code/pipe-echo-server/main.c
这是我的客户端代码:
#include <uv.h>
#include <stdio.h>
#include <stdlib.h>
void OnConnect(uv_connect_t* connect, int status){
printf("Hi!");
}
int main(){
uv_pipe_t* handle = (uv_pipe_t*)malloc(sizeof(uv_pipe_t));
uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
uv_pipe_open(handle, socket(PF_UNIX, SOCK_STREAM, 0));
int r;
uv_pipe_connect(connect, handle, "echo.sock", OnConnect);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}
但是一旦我 运行 它,它就会出现段错误。服务器确实给我一个进程已连接的消息。来自 GDB 的回溯:
Program received signal SIGSEGV, Segmentation fault.
uv__io_start (loop=0x0, w=w@entry=0x602098, events=events@entry=5)
at src/unix/core.c:787
787 src/unix/core.c: No such file or directory.
(gdb) backtrace full
#0 uv__io_start (loop=0x0, w=w@entry=0x602098, events=events@entry=5)
at src/unix/core.c:787
__PRETTY_FUNCTION__ = "uv__io_start"
#1 0x00007ffff7bc7ed8 in uv_pipe_connect (req=0x602120, handle=0x602010,
name=<optimized out>, cb=0x400870 <OnConnect>) at src/unix/pipe.c:188
saddr = {sun_family = 1,
sun_path = "echo.sock", '[=11=]0' <repeats 98 times>}
new_sock = 0
---Type <return> to continue, or q <return> to quit---
err = <optimized out>
r = <optimized out>
#2 0x0000000000400918 in main () at client.c:16
handle = 0x602010
connect = 0x602120
r = 0
您需要先初始化管道句柄才能使用它。
在 uv_pipe_open
之前添加此行:
uv_pipe_init(uv_default_loop(), handle, 0);
此外,casting the result of malloc
is unnecessary。
我们还必须使用有效的管道名称。例如:
#ifdef _WIN32
# define PIPENAME "\\?\pipe\some.name"
#elif defined(__android__)
# define PIPENAME "/data/local/tmp/some.name"
#else
# define PIPENAME "/tmp/some.name"
#endif
libuv 测试使用这个 same approach
工作示例:
#include <uv.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
# define PIPENAME "\\?\pipe\echo.sock"
#else
# define PIPENAME "echo.sock"
#endif
typedef struct {
uv_write_t req;
uv_buf_t buf;
} write_req_t;
void free_write_req(uv_write_t *req) {
write_req_t *wr = (write_req_t*) req;
free(wr->buf.base);
free(wr);
}
void on_write(uv_write_t *req, int status) {
if (status < 0) {
fprintf(stderr, "write error %s\n", uv_err_name(status));
} else {
puts("done.");
}
free_write_req(req);
}
void on_connect(uv_connect_t* connect, int status){
if (status < 0) {
puts("failed!");
} else {
puts("connected! sending msg...");
write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
req->buf = uv_buf_init("Hello World!", 13);
uv_write((uv_write_t*) req, connect->handle, &req->buf, 1, on_write);
}
}
int main(){
uv_loop_t *loop = uv_default_loop();
uv_pipe_t* handle = (uv_pipe_t*)malloc(sizeof(uv_pipe_t));
uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
uv_pipe_init(loop, handle, 0);
uv_pipe_connect(connect, handle, PIPENAME, on_connect);
uv_run(loop, UV_RUN_DEFAULT);
}
我正在尝试为以下示例代码使用 unix 管道开发一个简单的 echo 客户端:https://github.com/nikhilm/uvbook/blob/master/code/pipe-echo-server/main.c
这是我的客户端代码:
#include <uv.h>
#include <stdio.h>
#include <stdlib.h>
void OnConnect(uv_connect_t* connect, int status){
printf("Hi!");
}
int main(){
uv_pipe_t* handle = (uv_pipe_t*)malloc(sizeof(uv_pipe_t));
uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
uv_pipe_open(handle, socket(PF_UNIX, SOCK_STREAM, 0));
int r;
uv_pipe_connect(connect, handle, "echo.sock", OnConnect);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}
但是一旦我 运行 它,它就会出现段错误。服务器确实给我一个进程已连接的消息。来自 GDB 的回溯:
Program received signal SIGSEGV, Segmentation fault.
uv__io_start (loop=0x0, w=w@entry=0x602098, events=events@entry=5)
at src/unix/core.c:787
787 src/unix/core.c: No such file or directory.
(gdb) backtrace full
#0 uv__io_start (loop=0x0, w=w@entry=0x602098, events=events@entry=5)
at src/unix/core.c:787
__PRETTY_FUNCTION__ = "uv__io_start"
#1 0x00007ffff7bc7ed8 in uv_pipe_connect (req=0x602120, handle=0x602010,
name=<optimized out>, cb=0x400870 <OnConnect>) at src/unix/pipe.c:188
saddr = {sun_family = 1,
sun_path = "echo.sock", '[=11=]0' <repeats 98 times>}
new_sock = 0
---Type <return> to continue, or q <return> to quit---
err = <optimized out>
r = <optimized out>
#2 0x0000000000400918 in main () at client.c:16
handle = 0x602010
connect = 0x602120
r = 0
您需要先初始化管道句柄才能使用它。
在 uv_pipe_open
之前添加此行:
uv_pipe_init(uv_default_loop(), handle, 0);
此外,casting the result of malloc
is unnecessary。
我们还必须使用有效的管道名称。例如:
#ifdef _WIN32
# define PIPENAME "\\?\pipe\some.name"
#elif defined(__android__)
# define PIPENAME "/data/local/tmp/some.name"
#else
# define PIPENAME "/tmp/some.name"
#endif
libuv 测试使用这个 same approach
工作示例:
#include <uv.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
# define PIPENAME "\\?\pipe\echo.sock"
#else
# define PIPENAME "echo.sock"
#endif
typedef struct {
uv_write_t req;
uv_buf_t buf;
} write_req_t;
void free_write_req(uv_write_t *req) {
write_req_t *wr = (write_req_t*) req;
free(wr->buf.base);
free(wr);
}
void on_write(uv_write_t *req, int status) {
if (status < 0) {
fprintf(stderr, "write error %s\n", uv_err_name(status));
} else {
puts("done.");
}
free_write_req(req);
}
void on_connect(uv_connect_t* connect, int status){
if (status < 0) {
puts("failed!");
} else {
puts("connected! sending msg...");
write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
req->buf = uv_buf_init("Hello World!", 13);
uv_write((uv_write_t*) req, connect->handle, &req->buf, 1, on_write);
}
}
int main(){
uv_loop_t *loop = uv_default_loop();
uv_pipe_t* handle = (uv_pipe_t*)malloc(sizeof(uv_pipe_t));
uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t));
uv_pipe_init(loop, handle, 0);
uv_pipe_connect(connect, handle, PIPENAME, on_connect);
uv_run(loop, UV_RUN_DEFAULT);
}