2

I'm trying to develop a simple echo client using unix pipes for the following example code: https://github.com/nikhilm/uvbook/blob/master/code/pipe-echo-server/main.c

this is my client code:

#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);
}

But as soon as I run it, it segfaults. The server does give me a message that a process has connected. A backtrace from 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", '\000' <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
4

2 回答 2

4

您需要先初始化管道句柄,然后才能使用它。

在之前添加这一行uv_pipe_openuv_pipe_init(uv_default_loop(), handle, 0);

此外,强制转换结果malloc是不必要的。

于 2015-03-29T15:31:47.177 回答
1

我们还必须使用有效的管道名称。例如:

#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 测试使用相同的方法

工作示例:

#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);
}
于 2017-04-28T19:22:50.667 回答