nc.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "hloop.h"
  2. #include "hbase.h"
  3. #include "hsocket.h"
  4. #define RECV_BUFSIZE 8192
  5. static char recvbuf[RECV_BUFSIZE];
  6. // 1:tcp 2:udp
  7. int protocol = 1;
  8. // for stdin
  9. hio_t* stdinio = NULL;
  10. // for udp
  11. struct sockaddr* peeraddr = NULL;
  12. socklen_t peeraddrlen = sizeof(struct sockaddr_in6);
  13. // for tcp
  14. hio_t* sockio = NULL;
  15. int verbose = 0;
  16. void on_recv(hio_t* io, void* buf, int readbytes) {
  17. //printf("on_recv fd=%d readbytes=%d\n", hio_fd(io), readbytes);
  18. if (verbose) {
  19. char localaddrstr[SOCKADDR_STRLEN] = {0};
  20. char peeraddrstr[SOCKADDR_STRLEN] = {0};
  21. printf("[%s] <=> [%s]\n",
  22. SOCKADDR_STR(hio_localaddr(io), localaddrstr),
  23. SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
  24. }
  25. printf("%s", (char*)buf);
  26. fflush(stdout);
  27. }
  28. void on_stdin(hio_t* io, void* buf, int readbytes) {
  29. //printf("on_stdin fd=%d readbytes=%d\n", hio_fd(io), readbytes);
  30. //printf("> %s\n", buf);
  31. // CR|LF => CRLF for test most protocols
  32. char* str = (char*)buf;
  33. char eol = str[readbytes-1];
  34. if (eol == '\n' || eol == '\r') {
  35. if (readbytes > 1 && str[readbytes-2] == '\r' && eol == '\n') {
  36. // have been CRLF
  37. }
  38. else {
  39. ++readbytes;
  40. str[readbytes - 2] = '\r';
  41. str[readbytes - 1] = '\n';
  42. }
  43. }
  44. hio_write(sockio, buf, readbytes);
  45. }
  46. void on_close(hio_t* io) {
  47. //printf("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
  48. hio_del(stdinio, READ_EVENT);
  49. }
  50. void on_connect(hio_t* io) {
  51. //printf("on_connect fd=%d\n", hio_fd(io));
  52. if (verbose) {
  53. char localaddrstr[SOCKADDR_STRLEN] = {0};
  54. char peeraddrstr[SOCKADDR_STRLEN] = {0};
  55. printf("connect connfd=%d [%s] => [%s]\n", hio_fd(io),
  56. SOCKADDR_STR(hio_localaddr(io), localaddrstr),
  57. SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
  58. }
  59. hio_read(io);
  60. }
  61. int main(int argc, char** argv) {
  62. if (argc < 3) {
  63. printf("\
  64. Usage: cmd [-ut] host port\n\
  65. Options:\n\
  66. -t Use tcp protocol (default)\n\
  67. -u Use udp protocol\n\
  68. Examples: nc 127.0.0.1 80\n\
  69. nc -u 127.0.0.1 80\n");
  70. return -10;
  71. }
  72. int index = 1;
  73. const char* protocolname;
  74. if (argv[1][0] == '-') {
  75. ++index;
  76. if (argv[1][1] == 't') {
  77. protocol = 1;
  78. protocolname = "tcp";
  79. }
  80. else if (argv[1][1] == 'u') {
  81. protocol = 2;
  82. protocolname = "udp";
  83. }
  84. }
  85. const char* host = argv[index++];
  86. int port = atoi(argv[index++]);
  87. if (verbose) {
  88. printf("%s %s %d\n", protocolname, host, port);
  89. }
  90. MEMCHECK;
  91. hloop_t* loop = hloop_new(0);
  92. // stdin
  93. stdinio = hread(loop, 0, recvbuf, RECV_BUFSIZE, on_stdin);
  94. if (stdinio == NULL) {
  95. return -20;
  96. }
  97. // socket
  98. if (protocol == 1) {
  99. // tcp
  100. sockio = create_tcp_client(loop, host, port, on_connect);
  101. }
  102. else if (protocol == 2) {
  103. // udp
  104. sockio = create_udp_client(loop, host, port);
  105. hio_read(sockio);
  106. }
  107. if (sockio == NULL) {
  108. return -20;
  109. }
  110. //printf("sockfd=%d\n", hio_fd(sockio));
  111. hio_setcb_close(sockio, on_close);
  112. hio_setcb_read(sockio, on_recv);
  113. hio_set_readbuf(sockio, recvbuf, RECV_BUFSIZE);
  114. hloop_run(loop);
  115. hloop_free(&loop);
  116. return 0;
  117. }