#include <stdio.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/socket.h> #include "my_type.h" //外部头文件 申明了一个函数体 exec_cmd() int main(void) { char buf[2048];//为了保持程序简短,便于阅读,省去了错误判断。 int socket_fd; struct sockaddr_in netaddr; unsigned short int port=8000; socket_fd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); bzero(buf,2048); bzero(&netaddr,sizeof(struct sockaddr_in));//为了保持程序简短,便于阅读,省去了错误判断。 netaddr.sin_family=AF_INET; netaddr.sin_port=htons(port); netaddr.sin_addr.s_addr=htonl(INADDR_ANY); bind(socket_fd,(struct sockaddr *)&netaddr,sizeof(struct sockaddr));//在实际代码中,已加入了错误判断 listen(socket_fd,3); while(1) { int connfd; int i=0; char ch=0; char os_chose[4]; int len=sizeof(struct sockaddr); struct sockaddr_in cliaddr; char buf_in[2048]; bzero(os_chose,4); bzero(&cliaddr,sizeof(struct sockaddr_in)); printf("port = %d \n",ntohs(netaddr.sin_port)); start: connfd=accept(socket_fd,(struct sockaddr *)&cliaddr,&len);//监听端口 等待客户端连接 printf(" accept is over, remote ip = \n "); while(1) { strcpy(buf," chose your system : \r\n"); write(connfd,buf,30); strcpy(buf,"\r [1] windons \n"); write(connfd,buf,60); strcpy(buf,"\r [2] linux \n"); write(connfd,buf,60); read(connfd,os_chose,4);
/*window 与linux 有一些小区别,linux中,换行会自动回车,
而window只会换行而不会自动回车,所以如果对于从linux中获取的命令输出,
不做处理的话,在window终端下,会呈现梯形显示 */ if( strpbrk(os_chose,"1")!=NULL ) { ch='1'; printf("window \n"); break; } else if( strpbrk(os_chose,"2")!=NULL ) { ch='2'; printf(" linux \n"); break; } // window的telnet程序,按每个字符发送,而首字符往往不是输入的字符,可能是\0,没有去深究,
直接捕获输入的前4个字符,
然后检查是否1 或者2 来判断登陆者选择的系统类型。 } strcpy(buf,"\r\ntelnet_shell>>"); write(connfd,buf,20); //输入提示符 bzero(&buf,2048); while(1) { char tmp_ch=0; if(connfd>=0) { if(ch=='2')//linux的telnet客户端,以回车符作为命令的结束,与window不同,
要想去别对待,这样服务端获取的就是一个字符串 { bzero(&buf,2048); read(connfd,buf,2048); if( exec_cmd(buf,connfd)==10 )//my_type.h 申明的函数,主要解释输入的字符串命令,执行命令后,将标准输出和错误输出都重定向到网络中。 goto start; bzero(&buf,2048); strcpy(buf,"\rtelnet_shell>>"); write(connfd,buf,20); bzero(&buf,2048); } if(ch=='1') { // window的telnet客户端,按单个字符发送命令,所以要对输入的单个字符重新组合。 read(connfd,&tmp_ch,1); if(tmp_ch=='\0'&&i==0) {} else if(tmp_ch!='\n') buf_in[i++]=tmp_ch; else if(tmp_ch=='\n'&&i!=0) { printf("%s \n",buf_in); buf_in[i]=' '; buf_in[i+1]=' '; buf_in[i+2]='\n'; if( exec_cmd(buf_in,connfd)==10 ) goto start; bzero(&buf_in,2048); strcpy(buf_in,"\rtelnet_shell>>"); write(connfd,buf_in,20); bzero(&buf_in,2048); i=0; } } } } } return 0; }
|