2015-03-29 3 views
2

Я пытаюсь разработать простой эхо-клиент с помощью Unix трубы для следующего примера кода: https://github.com/nikhilm/uvbook/blob/master/code/pipe-echo-server/main.clibuv простой эхо-клиент

это мой код клиента:

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

Но как только я бегу это, это segfaults. Сервер дает мне сообщение о том, что процесс подключен. Ответ от GDB:

Program received signal SIGSEGV, Segmentation fault. 
uv__io_start (loop=0x0, [email protected]=0x602098, [email protected]=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, [email protected]=0x602098, [email protected]=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 
+0

о вызовах в таНос(): 1) в C, возвращенное значение из таНос (и семьи) 2) возвращаемое значение из malloc всегда должно быть проверено, чтобы убедиться, что операция прошла успешно – user3629249

ответ

4

Вам необходимо инициализировать ручку трубы, прежде чем вы сможете ее использовать.

Добавить эту строку перед uv_pipe_open: uv_pipe_init(uv_default_loop(), handle, 0);

Также casting the result of malloc is unnecessary.

0

В Windows мы должны использовать правильные имена труб. например:

#ifdef _WIN32 
# define PIPENAME "\\\\?\\pipe\\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) { 
    printf("failed!"); 
    } else { 
    printf("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); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^