main.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <uv.h>
  5. #define DEFAULT_PORT 7000
  6. #define DEFAULT_BACKLOG 128
  7. uv_loop_t *loop;
  8. struct sockaddr_in addr;
  9. typedef struct {
  10. uv_write_t req;
  11. uv_buf_t buf;
  12. } write_req_t;
  13. void free_write_req(uv_write_t *req) {
  14. write_req_t *wr = (write_req_t*) req;
  15. free(wr->buf.base);
  16. free(wr);
  17. }
  18. void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
  19. buf->base = (char*) malloc(suggested_size);
  20. buf->len = suggested_size;
  21. }
  22. void on_close(uv_handle_t* handle) {
  23. free(handle);
  24. }
  25. void echo_write(uv_write_t *req, int status) {
  26. if (status) {
  27. fprintf(stderr, "Write error %s\n", uv_strerror(status));
  28. }
  29. free_write_req(req);
  30. }
  31. void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
  32. if (nread > 0) {
  33. write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
  34. req->buf = uv_buf_init(buf->base, nread);
  35. uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write);
  36. return;
  37. }
  38. if (nread < 0) {
  39. if (nread != UV_EOF)
  40. fprintf(stderr, "Read error %s\n", uv_err_name(nread));
  41. uv_close((uv_handle_t*) client, on_close);
  42. }
  43. free(buf->base);
  44. }
  45. void on_new_connection(uv_stream_t *server, int status) {
  46. if (status < 0) {
  47. fprintf(stderr, "New connection error %s\n", uv_strerror(status));
  48. // error!
  49. return;
  50. }
  51. uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
  52. uv_tcp_init(loop, client);
  53. if (uv_accept(server, (uv_stream_t*) client) == 0) {
  54. uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read);
  55. }
  56. else {
  57. uv_close((uv_handle_t*) client, on_close);
  58. }
  59. }
  60. int main() {
  61. loop = uv_default_loop();
  62. uv_tcp_t server;
  63. uv_tcp_init(loop, &server);
  64. uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr);
  65. uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);
  66. int r = uv_listen((uv_stream_t*) &server, DEFAULT_BACKLOG, on_new_connection);
  67. if (r) {
  68. fprintf(stderr, "Listen error %s\n", uv_strerror(r));
  69. return 1;
  70. }
  71. return uv_run(loop, UV_RUN_DEFAULT);
  72. }