c/c++语言开发共享模拟telnet协议C语言客户端程序

首先要了解telnet协议,一下两篇blog给了我初步的思路 https://www.cnblogs.com/liang ling/p/5833489.html 这篇有比较基础的介绍 以及IAC命令含义解释 https://www.cnblogs.com/image eye/archive/2012 …

首先要了解telnet协议,一下两篇blog给了我初步的思路
https://www.cnblogs.com/liang-ling/p/5833489.html 这篇有比较基础的介绍 以及iac命令含义解释
https://www.cnblogs.com/image-eye/archive/2012/03/28/2421726.html 这篇就很能抓住重点 另外这位博主使用的是c# 写的程序十分完整 我这里关于iac指令处理有部分是直接借鉴他的程序 因此注释都没有修改仍然使用的是他的注释

以上两篇大致看过之后 就可以了解本次po出来的程序了 内容较为朴素

utils.h

#ifndef __utils__h #define __utils__h  #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <errno.h> #include <malloc.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/ioctl.h> #include <stdarg.h> #include <fcntl.h> #include <fcntl.h> #include <sys/poll.h> #include <signal.h> #include <sys/wait.h>  typedef signed long int ssize_t; typedef unsigned long int size_t;  ssize_t readn(int fd, void *vptr,size_t n); ssize_t writen(int fd, const void *vptr, size_t n); ssize_t readline(int fd,void *vptr,size_t maxlen);  #endif 

utils.c

 #include"utils.h"   ssize_t readn(int fd, void *vptr,size_t n) {     size_t nleft;     ssize_t nread;     char *ptr;          ptr = vptr;     nleft = n;     while(nleft >0)     {         if((nread = read(fd,ptr,nleft))<0)         {             if(errno == eintr)//error:为eagain,表示在非阻塞下,此时无数据到达,立即返回。                 nread = 0;            //error:为eintr,表示被信号中断了。             else                 return (-1);         }         else if(nread == 0)             break;         else              /* do nothing */         nleft -= nread;         ptr += nread;     }     return n-nleft;//实际读了多少字节 }  ssize_t writen(int fd, const void *vptr, size_t n) {     size_t nleft;     ssize_t nwritten;     const char *ptr;          ptr = vptr;     nleft = n;     while(nleft > 0)     {         if((nwritten = write(fd,ptr,nleft)) < 0)         {             if(nwritten <0 &&  errno == eintr)             {                 nwritten = 0;             }             else                 return (-1);         }         else if(nwritten == 0)                break;         else //nwritten > 0         {             /*do nothing*/         }         nleft = nleft - nwritten;         ptr = ptr + nwritten;     }     return (n- nleft);//实际写了多少字节 }  ssize_t readline(int fd,void *vptr,size_t maxlen) {     ssize_t n =0,rc;     char c,*ptr;          ptr = vptr;     while(1)     {         if((rc = read(fd,&c,1)) == 1)         {             *ptr++ = c;             n++;             if(c == 'n')                 break;         }         else if (rc == 0)         {             *ptr = '';             return (n -1);         }         else         {             if(errno == eintr)                 continue;             else                 return (-1);         }     }     *ptr = '';     return n; } 

telnet.h

 #ifndef __telnet__h #define __telnet__h  //<iac cmd op >  #define iac   255  //command word #define nul        0 #define bel        7 #define bs         8 #define ht         9 #define lf         10 #define vt         11 #define ff         12 #define cr         13 #define se         240 #define nop        241 #define dm         242 #define brk        243 #define ip         244 #define ao         245 #define ayt        246 #define ec         247 #define el         248 #define ga         249 #define sb         250 #define will       251 #define wont       252 #define do         253 #define dont       254  typedef unsigned char uint8; typedef unsigned int  uint32;   //operation options  typedef enum tagoperation_options {     topt_bin = 0,     topt_echo = 1,     topt_recn = 2,     topt_supp = 3      }operation_options;   uint32 get_every_frame(uint8* recvbuf,uint32 len,uint8* sendbuf,uint32 sendlen);  #endif 

telnet.c

    #include"telnet.h" #include<string.h> #include<stdio.h>   #define maxline 1024 #define send    1 #define is      0    static uint32 handle_telnetcmd_from_server(uint8* buf,uint32 len,uint8* resp,uint32 n); static uint32 process_every_frame(uint8* startbyte,uint8* endbyte,uint8* sendbuf,uint32 startsendbyte);   uint32 get_every_frame(uint8* recvbuf,uint32 len,uint8* sendbuf,uint32 sendlen) {     uint32 i =0,n=0,sum =0;     //uint8* p = sendbuf;     uint8* prear = &recvbuf[len];     uint8* startbyte = recvbuf;     uint8* endbyte = recvbuf;          printf("-sum-receivelen----%d-------n",len);     printf("receive :<*");          for(i =0 ;i<len;i++)     {         printf("%x*",recvbuf[i]);     }     printf("*>n");                    while(startbyte != prear)     {         if(*startbyte == iac)         {             sum = sum + n;             switch(*(++endbyte))             {         /*fa 250 */case sb:while(*(++endbyte) != se){};n = process_every_frame(startbyte,endbyte,sendbuf,sum);break;         /*fb 251 */case will:endbyte +=2;n = process_every_frame(startbyte,endbyte,sendbuf,sum);break;         /*fc 252 */case wont:endbyte +=2;n = process_every_frame(startbyte,endbyte,sendbuf,sum);break;         /*fd 253 */case do:endbyte +=2;n = process_every_frame(startbyte,endbyte,sendbuf,sum);break;         /*fe 254 */case dont:endbyte +=2;n = process_every_frame(startbyte,endbyte,sendbuf,sum);break;           /* 240 */case se:break;         /* sss */default : break;             }         }         startbyte = endbyte;     }     if(sum > sendlen)     {         printf("--error3---sum > maxline-----n");     }     printf("--------------sum is %d ----n",sum);     return sum; }    static uint32 process_every_frame(uint8* startbyte,uint8* endbyte,uint8* sendbuf,uint32 startsendbyte) {     uint8 n = 0 ;     uint8* pstartbyte = startbyte;          while(pstartbyte != endbyte)     {         n++;         pstartbyte++;     }     return handle_telnetcmd_from_server(startbyte,n,&sendbuf[startsendbyte],maxline); }  static uint32 handle_telnetcmd_from_server(uint8* buf,uint32 len,uint8* resp,uint32 n) {     uint32 i =0;     uint8 *p = resp;     operation_options optioncode;     uint8 cmdcode,ch;     uint32 resplen =0;     memset(resp,0,len);     //first display cmd from server in string          printf("--receivelen----%d-------n",len);     printf("receive :<*");     for(i =0 ;i<len;i++)     {         printf("%x*",buf[i]);     }     printf("*>n");          if(len < 3)     {         printf("iac command length is %d less then 3n",len);         return -1;     }          //获得命令码     cmdcode = buf[1];     //获得选项码     optioncode = buf[2];               //response requests from server          *p = iac;     resplen++;     if(optioncode == topt_echo || optioncode == topt_supp)     {         if (cmdcode == do)         {             //我设置我应答的命令码为 251(will) 即为支持 回显或抑制继续进行             ch = will;             *(++p) = ch;             *(++p)= optioncode;             resplen += 2;          }         //如果命令码为 254(dont)         else if (cmdcode == dont)         {             //我设置我应答的命令码为 252(wont) 即为我也会"拒绝启动" 回显或抑制继续进行             ch = wont;             *(++p)= ch;             *(++p)= optioncode;             resplen += 2;          }         //如果命令码为251(will)         else if (cmdcode == will)         {             //我设置我应答的命令码为 253(do) 即为我认可你使用回显或抑制继续进行             ch = do;             *(++p)= ch;             *(++p)= optioncode;             resplen += 2;             //break;         }         //如果接受到的命令码为251(wont)          else if (cmdcode == wont)         {             //应答  我也拒绝选项请求回显或抑制继续进行             ch = dont;             *(++p)= ch;             *(++p)= optioncode;             resplen += 2;             //    break;         }         //如果接受到250(sb,标志子选项开始)         else if (cmdcode == sb)         {             /*              * 因为启动了子标志位,命令长度扩展到了4字节,              * 取最后一个标志字节为选项码              * 如果这个选项码字节为1(send)              * 则回发为 250(sb子选项开始) + 获取的第二个字节 + 0(is) + 255(标志位iac) + 240(se子选项结束)             */             ch = buf[3];             if (ch == send)             {                 ch = sb;                 *(++p)= ch;                 *(++p)= optioncode;                 *(++p)= is;                 *(++p)= iac;                 *(++p)= se;                 resplen += 5;             }             else             {                 printf("ch != sendn");             }         }         else         {             /* do nothing */         }     }     else/* 如果选项码不是1 或者3  */     {         // 底下一系列代表,无论你发那种请求,我都不干         if (cmdcode == do)         {             ch = wont;             *(++p)= ch;             *(++p)= optioncode;             resplen += 2;         }         else if (cmdcode == dont)         {             ch = wont;             *(++p)= ch;             *(++p)= optioncode;             resplen += 2;         }         else if (cmdcode == will)         {             ch = dont;             *(++p)= ch;             *(++p)= optioncode;             resplen += 2;         }         else if (cmdcode == wont)         {             ch = dont;             *(++p)= ch;             *(++p)= optioncode;             resplen += 2;         }         else         {             /* do nothing */         }                  }          printf("--resplen---%d-------n",resplen);     printf("response :<*");     for(i =0 ;i<resplen;i++)     {         printf("%x*",resp[i]);     }     printf("*>n");                    if(n < resplen )     {         printf("error n < resplen !!! n");     }     if(resplen < 3 )     {         printf("resplen < 3 n");     }     return resplen; } 

client.c

 //gcc client.c -o client   #include"utils.h" #include"telnet.h"   #define ip_address   "127.0.0.1" #define ip_port      23 #define serv_port    3333 #define maxline      1024  typedef struct sockaddr sa;   void str_cli(file *fp,uint32 sockfd); uint32 max(uint32 a,uint32 b); void err_exit(char* s);  uint32 main(uint32 argc,uint32 **argv) {     uint32 sockfd,isready=0;     struct sockaddr_in servaddr;     uint32 hname[128];      sockfd = socket(af_inet,sock_stream,0);     bzero(&servaddr,sizeof(servaddr));     servaddr.sin_family = af_inet;     servaddr.sin_port = htons(ip_port);     servaddr.sin_addr.s_addr = inet_addr(ip_address);     printf("servaddr: ip is %s, port is %dn",inet_ntoa(servaddr.sin_addr), ntohs(servaddr.sin_port));      while(connect(sockfd,(sa*)&servaddr,sizeof(servaddr))){};     printf("connect has been readyn");          str_cli(stdin,sockfd);     exit(0);     return 0; } void err_exit(char* s) {     perror(s);     exit(exit_failure); } void info_print(char* s) {     printf("%s",s); } uint32 max(uint32 a,uint32 b) {     return (a>b?a:b); }  void str_cli(file *fp,uint32 sockfd) {     uint32 maxfdp1,nready;//stdineof;     fd_set rset;     uint8 buf[maxline];     uint8 respbuff[maxline] = {0};;     uint32 resplen;     uint32 n;     uint8 echo_cmd[] = {0xff,0xfb,0x01};     //stdineof = 0;     fd_zero(&rset);     writen(sockfd,echo_cmd,3);          for(;;)     {         //if(stdineof == 0)         fd_set(fileno(fp),&rset);         fd_set(sockfd,&rset);         maxfdp1 = max(fileno(fp),sockfd)+1;         nready = select(maxfdp1,&rset,null,null,null);                  if(nready < 0)         {             err_exit("error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");         }                  if(fd_isset(sockfd,&rset))         {             memset(buf,0,maxline);             if((n = read(sockfd,buf,maxline))==0)             {                 err_exit("str_cli:server termination prematurely");             }             buf[n] = '';             //printf("fd_isset(sockfd,&rset)-------------%sn",buf);                          if(buf[0] == iac)             {                 memset(respbuff,0,maxline);                 resplen = get_every_frame(buf,n,respbuff,maxline);                 writen(sockfd,respbuff,resplen);             }             else             {                 writen(fileno(stdout),(char *)buf,n);             }                          //writen(fileno(stdout),buf,n);         }         if(fd_isset(fileno(fp),&rset))         {             memset(buf,0,maxline);             if((n = readline(fileno(fp),(char *)buf,maxline)) == 0)             {                 //stdineof = 1;//此时碰到eof 并且马上要发生fin序列 所以标准输入不可读了                 shutdown(sockfd,shut_wr);                 fd_clr(fileno(fp),&rset);                 info_print("nothing input!");                 continue;             }             else if(n >0)             {                 /* do nothing */             }             else             {                 err_exit("some error occurred ");             }             //printf("fd_isset(fileno(fp),&rset)----%d--n",n);             //memset(buf,0,maxline);             writen(sockfd,(char *)buf,n);         }     } }

makefile

all:client_telnet     @echo ""     @echo "this is telnet client compile......."     @echo ""      client_telnet:client.o utils.o telnet.o     gcc -g -o client_telnet client.o utils.o telnet.o      client.o:client.c utils.h telnet.h     gcc -g -c client.c      utils.o:utils.c utils.h     gcc -g -c utils.c       telnet.o:telnet.c telnet.h     gcc -g -c telnet.c      clean :     -rm client.o utils.o telnet.o client_telnet

以上为本次程序使用的源码 程序在linux系统上运行方式为 ./client_telnet

然后是运行截图如此下:

模拟telnet协议C语言客户端程序

模拟telnet协议C语言客户端程序

模拟telnet协议C语言客户端程序

以上

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/601356.html

(0)
上一篇 2021年5月9日
下一篇 2021年5月9日

精彩推荐