telnet编程 客户端 服务器

本文介绍了作者在学习ssh协议过程中,先实现了一套telnet服务。详细讲述了客户端如何处理NVT ASCII值,包括方向键和其他特殊键的映射。还讨论了服务器端如何处理命令操作,如通过system调用来获取命令输出,并将其反馈给客户端。服务器端的实现考虑了多客户端同时访问的情况。最后,简要提到了代码下载链接。

    最近学习ssh协议,为了方便,自己先实现一套telnet服务,以便之后套用ssh(自己进了一个深坑)。

    客户端:

    先从telnet客户端做起。这里先给出RFC的中文文档链接:http://oss.org.cn/man/develop/rfc/RFC854.txt 。基本上把telnet介绍得差不多了。但关于NVT的介绍太少,也没有给出一个标准。就比如说键盘的方向键ASCII映射NVT不知道是什么。网上查了很久的资料都没有找到。最终通过自己抓包权威的telnet软件才知道方向键与其他一些按键的NVT ASCII值。现在找到了一些关于NVTASCII的说明文档:http://oss.org.cn/man/develop/rfc/RFC698.txt  就上键来说,getch()收到的值是十进制:224 72 ,转换为ASCII是十进制 27 91 65 (/033[A),下是27 91 66 (/033[B)。因为没找到其他的标准,我就只处理了方向以及退格键的一些必要NVTASCII。

    拿了两个权威的telnet服务器来测试,一个是我的centos服务器的telnet,一个是我的win服务器自带的的telnet。

    键盘的获取使用conio.h下的getch函数,使用这个函数要注意不要阻塞IO,最好是使用_kbhit函数来检测键盘是否有输入再getch,否则可能会出现getch阻塞时,另外线程的IO也会等待getch的结束而阻塞。另外需要注意Ctrl+C、Ctrl+Z之类会直接影响到程序执行过程的输入,需要额外处理。

    客户端连接centos服务器:

    doc.h 头文件:

#ifndef DOC_H_INCLUDED
#define DOC_H_INCLUDED

#define BS      (char)8
#define LF      (char)10
#define CR      (char)13

#define ESC     (char)27

#define SPACE   (char)32

#define MFLAG   (char)91

#define MARK    (char)224

#define SE      (char)240
#define NOP     (char)241
#define DM      (char)242
#define BRK     (char)243
#define IP      (char)244
#define AO      (char)245
#define AYT     (char)246
#define EC      (char)247
#define EL      (char)248
#define GA      (char)249
#define SB      (char)250
#define WILL    (char)251
#define WONT    (char)252
#define DO      (char)253
#define DON'T   (char)254
#define IAC     (char)255


#endif // DOC_H_INCLUDED

telnet客户端代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <conio.h>
#include <windows.h>
#include <winsock2.h>

#include "doc.h"

//简单的方向键与NVT映射
int mhash[1000];
void init()
{
    mhash[72]='A';
    mhash[80]='B';
    mhash[77]='C';
    mhash[75]='D';;
}

SOCKET sock;//唯一用来通信的SOCKET
HANDLE inputth,outputth;//两个线程句柄
UINT inputthread(LPVOID Param);//输入与发送线程
UINT outputthread(LPVOID Param);//输出与接收线程

int main(int num,char *arr[])//程序的调用参数,接受ip和port
{
    if(num<2)
    {
        puts("no address");
        return false;
    }
    init();
    WSADATA wsadata;
    if(WSAStartup(MAKEWORD(1,0),&wsadata))
    {
        return -1;
    }

    sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sock==INVALID_SOCKET)
    {
        return -1;
    }
    sockaddr_in addr;
    addr.sin_family=AF_INET;
    //绑定端口,默认值23端口
    if(num>2)
    {
        addr.sin_port=htons(atoi(arr[2]));
    }
    else
    {
        addr.sin_port=htons(23);
    }
    //解析域名IP
    hostent *hname=gethostbyname(arr[1]);
    if(!hname)
    {
        puts("can't find address");
        return -1;
    }//puts(inet_ntoa(addr.sin_addr));
    addr.sin_addr.S_un.S_addr=*(u_long *)hname->h_addr_list[0];

    //puts(hname->h_addr_list[0]);
    //puts(inet_ntoa(addr.sin_addr));

    if(SOCKET_ERROR==connect(sock,(sockaddr *)&addr,sizeof(addr)))
    {
        return -1;
    }
  &n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值