Linux上C语言写的简易telnet客户端

telnet.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/socket.h>
  4. #include <arpa/inet.h>
  5. #include <netinet/in.h>
  6. #include <netdb.h>
  7. #include <unistd.h>
  8. #include <errno.h>
  9. #include <signal.h>
  10. #include <time.h>
  11. #include <stdarg.h>
  12. #define ERR_EXIT(m, ...) \
  13. do { \
  14. fprintf(stderr, m"\n", ##__VA_ARGS__); \
  15. log(m"\n", ##__VA_ARGS__); \
  16. exit(EXIT_FAILURE); \
  17. } while (0)
  18. #define MAX_BUFF_LEN 1024
  19. void log(const char *fmt, ...)
  20. {
  21. char buffer[MAX_BUFF_LEN] = {0};
  22. va_list args;
  23. time_t timep;
  24. time(&timep);
  25. struct tm *p = gmtime(&timep);
  26. FILE* fp = fopen("telnet.log", "a+");
  27. if(fp){
  28. snprintf(buffer, MAX_BUFF_LEN, "[%.4d-%.2d-%.2d %.2d:%.2d:%.2d][%d]", (1900+p->tm_year),(1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, getpid());
  29. va_start(args, fmt);
  30. vsnprintf(buffer + strlen(buffer), MAX_BUFF_LEN - strlen(buffer) - 1, fmt, args);
  31. va_end(args);
  32. fwrite(buffer, strlen(buffer), 1, fp);
  33. fclose(fp);
  34. }
  35. }
  36. ssize_t /* Write "n" bytes to a descriptor. */
  37. writen(int fd, const void *vptr, size_t n){
  38. size_t nleft;
  39. ssize_t nwritten;
  40. const char *ptr;
  41. ptr = vptr;
  42. nleft = n;
  43. while (nleft > 0) {
  44. if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
  45. if (nwritten < 0 && errno == EINTR)
  46. nwritten = 0; /* and call write() again */
  47. else
  48. return(-1); /* error */
  49. }
  50. nleft -= nwritten;
  51. ptr += nwritten;
  52. }
  53. return(n);
  54. }
  55. int main(int argc,char **argv){
  56. if(argc < 3){
  57. fprintf(stderr, "Usage: %s ServerIPAddress ServerPort\n",argv[0]);
  58. return 0;
  59. }
  60. fd_set rset;
  61. FD_ZERO(&rset);
  62. int sock = socket(AF_INET,SOCK_STREAM,0);
  63. struct sockaddr_in server_addr;
  64. memset(&server_addr, 0, sizeof(server_addr));
  65. server_addr.sin_family = AF_INET; //internet协议族
  66. struct hostent *h = gethostbyname(argv[1]);
  67. server_addr.sin_addr = *((struct in_addr *)h->h_addr);
  68. server_addr.sin_port = htons(atoi(argv[2]));
  69. if(connect(sock,(struct sockaddr*)&server_addr, sizeof(struct sockaddr_in)) < 0){
  70. ERR_EXIT("connect to %s:%s failed", argv[1], argv[2]);
  71. }
  72. fprintf(stdout, "% 9d\n", getpid());
  73. fflush(stdout);
  74. int nready;
  75. int maxfd;
  76. int fd_stdin = fileno(stdin);
  77. int fd_stdout = fileno(stdout);
  78. if (fd_stdin > sock)
  79. maxfd = fd_stdin;
  80. else
  81. maxfd = sock;
  82. char sendbuf[1024*4] = {0};
  83. char recvbuf[1024*4] = {0};
  84. while (1){
  85. FD_SET(fd_stdin, &rset);
  86. FD_SET(sock, &rset);
  87. nready = select(maxfd + 1, &rset, NULL, NULL, NULL); //select返回表示检测到可读事件
  88. if (nready == -1) ERR_EXIT("select error");
  89. if (nready == 0) continue;
  90. if (FD_ISSET(sock, &rset)){
  91. int ret = read(sock, recvbuf, sizeof(recvbuf)); //按行读取
  92. if (ret == -1) ERR_EXIT("read from socket error");
  93. else if (ret == 0) ERR_EXIT("server close"); //服务器关闭
  94. writen(fd_stdout, recvbuf, ret);
  95. memset(recvbuf, 0, sizeof(recvbuf));
  96. }
  97. if (FD_ISSET(fd_stdin, &rset)){
  98. int ret = read(fd_stdin, sendbuf, sizeof(sendbuf));
  99. if(ret > 0) {
  100. writen(sock, sendbuf, ret);
  101. memset(sendbuf, 0, sizeof(sendbuf));
  102. }else{
  103. ERR_EXIT("read from stdin error");
  104. }
  105. }
  106. }
  107. close(sock);
  108. exit(0);
  109. }
COPY

编译方法:

gcc -o telnet telnet.c

分享

Related Issues not found

Please contact @drunkdream to initialize the comment