libuv_echo.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #define _GNU_SOURCE 1
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "uv.h"
  6. typedef struct {
  7. uv_write_t req;
  8. uv_buf_t buf;
  9. } uv_write_req_t;
  10. void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
  11. buf->base = (char*)malloc(suggested_size);
  12. buf->len = suggested_size;
  13. }
  14. void close_cb(uv_handle_t* handle) {
  15. free(handle);
  16. }
  17. void write_cb(uv_write_t* req, int status) {
  18. uv_write_req_t* wr = (uv_write_req_t*)req;
  19. free(wr->buf.base);
  20. free(wr);
  21. }
  22. void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
  23. if (nread <= 0) {
  24. uv_close((uv_handle_t*)stream, close_cb);
  25. return;
  26. }
  27. uv_write_req_t* wr = (uv_write_req_t*)malloc(sizeof(uv_write_req_t));
  28. wr->buf.base = buf->base;
  29. wr->buf.len = nread;
  30. uv_write(&wr->req, stream, &wr->buf, 1, write_cb);
  31. }
  32. void do_accept(uv_stream_t* server, int status) {
  33. uv_tcp_t* tcp_stream = (uv_tcp_t*)malloc(sizeof(uv_tcp_t));
  34. uv_tcp_init(server->loop, tcp_stream);
  35. uv_accept(server, (uv_stream_t*)tcp_stream);
  36. uv_read_start((uv_stream_t*)tcp_stream, alloc_cb, read_cb);
  37. }
  38. int main(int argc, char** argv) {
  39. if (argc < 2) {
  40. printf("Usage: cmd port\n");
  41. return -10;
  42. }
  43. int port = atoi(argv[1]);
  44. uv_loop_t loop;
  45. uv_loop_init(&loop);
  46. struct sockaddr_in addr;
  47. memset(&addr, 0, sizeof(addr));
  48. //addr.sin_family = AF_INET;
  49. //addr.sin_port = htons(port);
  50. uv_ip4_addr("0.0.0.0", port, &addr);
  51. uv_tcp_t tcp_server;
  52. uv_tcp_init(&loop, &tcp_server);
  53. int ret = uv_tcp_bind(&tcp_server, (struct sockaddr*)&addr, 0);
  54. if (ret) {
  55. return -20;
  56. }
  57. ret = uv_listen((uv_stream_t*)&tcp_server, SOMAXCONN, do_accept);
  58. if (ret) {
  59. return -30;
  60. }
  61. uv_run(&loop, UV_RUN_DEFAULT);
  62. return 0;
  63. }