nc.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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", io->fd, readbytes);
  18. if (verbose) {
  19. char localaddrstr[INET6_ADDRSTRLEN+16] = {0};
  20. char peeraddrstr[INET6_ADDRSTRLEN+16] = {0};
  21. printf("[%s] <=> [%s]\n",
  22. sockaddr_snprintf(io->localaddr, localaddrstr, sizeof(localaddrstr)),
  23. sockaddr_snprintf(io->peeraddr, peeraddrstr, sizeof(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", io->fd, readbytes);
  30. //printf("> %s\n", buf);
  31. if (protocol == 1) {
  32. hsend(sockio->loop, sockio->fd, buf, readbytes, NULL);
  33. }
  34. else if (protocol == 2) {
  35. hsendto(sockio->loop, sockio->fd, buf, readbytes, NULL);
  36. hrecvfrom(sockio->loop, sockio->fd, recvbuf, RECV_BUFSIZE, on_recv);
  37. }
  38. }
  39. void on_close(hio_t* io) {
  40. //printf("on_close fd=%d error=%d\n", io->fd, io->error);
  41. hio_del(stdinio, READ_EVENT);
  42. }
  43. void on_connect(hio_t* io) {
  44. //printf("on_connect fd=%d\n", io->fd, state);
  45. if (verbose) {
  46. char localaddrstr[INET6_ADDRSTRLEN+16] = {0};
  47. char peeraddrstr[INET6_ADDRSTRLEN+16] = {0};
  48. printf("connect connfd=%d [%s] => [%s]\n", io->fd,
  49. sockaddr_snprintf(io->localaddr, localaddrstr, sizeof(localaddrstr)),
  50. sockaddr_snprintf(io->peeraddr, peeraddrstr, sizeof(peeraddrstr)));
  51. }
  52. hrecv(io->loop, io->fd, recvbuf, RECV_BUFSIZE, on_recv);
  53. }
  54. int main(int argc, char** argv) {
  55. if (argc < 3) {
  56. printf("\
  57. Usage: cmd [-ut] host port\n\
  58. Options:\n\
  59. -t Use tcp protocol (default)\n\
  60. -u Use udp protocol\n\
  61. Examples: nc 127.0.0.1 80\n\
  62. nc -u 127.0.0.1 80\n");
  63. return -10;
  64. }
  65. int index = 1;
  66. const char* protocolname;
  67. if (argv[1][0] == '-') {
  68. ++index;
  69. if (argv[1][1] == 't') {
  70. protocol = 1;
  71. protocolname = "tcp";
  72. }
  73. else if (argv[1][1] == 'u') {
  74. protocol = 2;
  75. protocolname = "udp";
  76. }
  77. }
  78. const char* host = argv[index++];
  79. int port = atoi(argv[index++]);
  80. if (verbose) {
  81. printf("%s %s %d\n", protocolname, host, port);
  82. }
  83. MEMCHECK;
  84. hloop_t loop;
  85. hloop_init(&loop);
  86. // stdin
  87. stdinio = hread(&loop, 0, recvbuf, RECV_BUFSIZE, on_stdin);
  88. if (stdinio == NULL) {
  89. return -20;
  90. }
  91. // socket
  92. if (protocol == 1) {
  93. // tcp
  94. sockio = create_tcp_client(&loop, host, port, on_connect);
  95. }
  96. else if (protocol == 2) {
  97. // udp
  98. sockio = create_udp_client(&loop, host, port);
  99. }
  100. if (sockio == NULL) {
  101. return -20;
  102. }
  103. //printf("sockfd=%d\n", sockio->fd);
  104. sockio->close_cb = on_close;
  105. hloop_run(&loop);
  106. return 0;
  107. }