




已阅读5页,还剩34页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
嵌入式网络协议LWIP移植lwIP是瑞士计算机科学院(Swedish Institute of Computer Science)的Adam Dunkels等开发的一套用于嵌入式系统的开放源代码TCP/IP协议栈。 Lwip既可以移植到操作系统上,又可以在无操作系统的情况下独立运行。LwIP的特性如下:(1)支持多网络接口下的IP转发(2)支持ICMP协议 (3)包括实验性扩展的的UDP(用户数据报协议)(4)包括阻塞控制,RTT估算和快速恢复和快速转发的TCP(传输控制协议)(5)提供专门的内部回调接口(Raw API)用于提高应用程序性能(6)可选择的Berkeley接口API(多线程情况下)(7)在最新的版本中支持ppp(8)新版本中增加了的IP fragment的支持(9)支持DHCP协议,动态分配ip地址。 现在网上有最新的版本。1、lwip的进程模型(process model)tcp/ip协议栈的process model一般有几种方式。1)tcp/ip协议的每一层是一个单独进程。链路层是一个进程,ip层是一个进程,tcp层是一个进程。这样的好处是网络协议的每一层都非常清晰,代码的调试和理解都非常容易。但是最大的坏处数据跨层传递时会引起上下文切换(context switch)。对于接收一个TCP segment要引起3次context switch(从网卡驱动程序到链路层进程,从链路层进程到ip层进程,从ip层进程到TCP进程)。通常对于操作系统来说,任务切换是要浪费时间的。过频的context swich是不可取的。2)另外一种方式是TCP/IP协议栈在操作系统内核当中。应用程序通过操作系统的系统调用(system call)和协议栈来进行通讯。这样TCP/IP的协议栈就限定于特定的操作系统内核了。如windows就是这种方式。3)lwip的process model:所有tcp/ip协议栈都在一个进程当中,这样tcp/ip协议栈就和操作系统内核分开了。而应用层程序既可以是单独的进程也可以驻留在tcp/ip进程中。如果应用程序是单独的进程可以通过操作系统的邮箱、消息队列等和tcp/ip进程进行通讯。如果应用层程序驻留tcp/ip进程中,那应用层程序就利用内部回调函数口(Raw API)和tcp/ip协议栈通讯。对于ucos来说进程就是一个系统任务。lwip的process model请参看下图。在图中可以看到整个tcp/ip协议栈都在同一个任务(tcpip_thread)中。应用层程序既可以是独立的任务(如图中的tftp_thread,tcpecho_thread),也可以在tcpip_thread中(如图左上角)中利用内部回调函数口(Raw API)和tcp/ip协议栈通讯。2、Port Lwip to uCos在这个实验系统中我们用的硬件平台是s3c44b0x+rtl8019。ucos在44b0上的移植在前面有非常详尽的讲解和移植代码。需要说明的一点是lwip会为每个网络连接动态分配一些信号量(semaphone)和消息队列(Message Queue),当连接断开时会删掉这些semaphone和Queue。而ucos-2.0不支持semaphone和Queue的删除,所以要选择一些较高版本的ucos。我们用的是ucos-2.51。2.1 Lwip的操作系统封装层(operating system emulation layer)Lwip为了适应不同的操作系统,在代码中没有使用和某一个操作系统相关的系统调用和数据结构。而是在lwip和操作系统之间增加了一个操作系统封装层。操作系统封装层为操作系统服务(定时、进程同步、消息传递)提供了一个统一的接口。在lwip中进程同步使用semaphone和消息传递采用”mbox”(其实在ucos的实现中我们使用的是Message Queue来实现lwip中的”mbox”,下面大家可以看到这一点)Operating system emulation layer的原代码在/lwip/src/core/sys.c中。而和具体的操作系统相关的代码在./lwip/src/arch/sys_arch.c中。操作系统封装层的主要函数如下:void sys_init(void)/系统初始化sys_thread_t sys_thread_new(void (* function)(void *arg), void *arg,int prio)/创建一个新进程sys_mbox_t sys_mbox_new(void)/创建一个邮箱voidsys_mbox_free(sys_mbox_t mbox)/释放并删除一个邮箱voidsys_mbox_post(sys_mbox_t mbox, void *data) /发送一个消息到邮箱void sys_mbox_fetch(sys_mbox_t mbox, void *msg)/等待邮箱中的消息sys_sem_t sys_sem_new(u8_t count)/创建一个信号量void sys_sem_free(sys_sem_t sem)/释放并删除一个信号量void sys_sem_signal(sys_sem_t sem)/发送一个信号量void sys_sem_wait(sys_sem_t sem)/等待一个信号量void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)/设置一个超时事件void sys_untimeout(sys_timeout_handler h, void *arg)/删除一个超时事件关于操作系统封装层的信息可以阅读lwip的doc目录下面的sys_arch.txt.文件。2.2 Lwip在ucos上的移植.2.2.1 系统初始化sys_int必须在tcpip协议栈任务tcpip_thread创建前被调用.#define MAX_QUEUES20#define MAX_QUEUE_ENTRIES20typedef struct OS_EVENT*pQ;/ucos中指向事件控制块的指针 void*pvQEntriesMAX_QUEUE_ENTRIES;/消息队列 /MAX_QUEUE_ENTRIES消息队列中最多消息数 TQ_DESCR, *PQ_DESCR;typedef PQ_DESCRsys_mbox_t;/可见lwip中的mbox其实是ucos的消息队列static char pcQueueMemoryPoolMAX_QUEUES * sizeof(TQ_DESCR) ;void sys_init(void)u8_t i;s8_tucErr;pQueueMem = OSMemCreate( (void*)pcQueueMemoryPool, MAX_QUEUES, sizeof(TQ_DESCR), &ucErr );/为消息队列创建内存分区/init lwip task prio offsetcurr_prio_offset = 0;/init lwip_timeouts for every lwip task/初始化lwip定时事件表,具体实现参考下面章节for(i=0;iLWIP_TASK_MAX;i+)lwip_timeoutsi.next = NULL;2.2.2 创建一个和tcp/ip相关新进程:lwip中的进程就是ucos中的任务,创建一个新进程的代码如下:#define LWIP_STK_SIZE10*1024/和tcp/ip相关任务的堆栈大小.可以根据情况自/己设置,44b0开发板上有8M的sdram,所以设大/一点也没有关系:)/max number of lwip tasks#define LWIP_TASK_MAX5 /和tcp/ip相关的任务最多数目/first prio of lwip tasks#define LWIP_START_PRIO5 /和tcp/ip相关任务的起始优先级,在本例中优先级可/以从(5-9).注意tcpip_thread在所有tcp/ip相关进程中/应该是优先级最高的.在本例中就是优先级5 /如果用户需要创建和tcp/ip无关任务,如uart任务等,/不要使用5-9的优先级OS_STK LWIP_TASK_STKLWIP_TASK_MAXLWIP_STK_SIZE;/和tcp/ip相关进程/的堆栈区u8_t curr_prio_offset ;sys_thread_t sys_thread_new(void (* function)(void *arg), void *arg,int prio)if(curr_prio_offset LWIP_TASK_MAX)OSTaskCreate(function,(void*)0x1111,&LWIP_TASK_STKcurr_prio_offsetLWIP _STK_SIZE-1, LWIP_START_PRIO+curr_prio_offset );curr_prio_offset+; return 1; else / PRINT( lwip task prio out of range ! error! );从代码中可以看出tcpip_thread应该是最先创建的。2.2.3 Lwip中的定时事件在tcp/ip协议中很多时候都要用到定时,定时的实现也是tcp/ip协议栈中一个重要的部分。lwip中定时事件的数据结构如下。 struct sys_timeout struct sys_timeout *next;/指向下一个定时结构u32_t time;/定时时间sys_timeout_handler h;/定时时间到后执行的函数void *arg;/定时时间到后执行函数的参数.;struct sys_timeouts struct sys_timeout *next;struct sys_timeouts lwip_timeoutsLWIP_TASK_MAX;Lwip中的定时事件表的结构如下图,每个和tcp/ip相关的任务的一系列定时事件组成一个单向链表。每个链表的起始指针存在lwip_timeouts的对应表项中。函数sys_arch_timeouts返回对应于当前任务的指向定时事件链表的起始指针。该指针存在lwip_timeoutsMAX_LWIP_TASKS中。struct sys_timeouts null_timeouts;struct sys_timeouts * sys_arch_timeouts(void)u8_t curr_prio;s16_t err,offset; OS_TCB curr_task_pcb;null_timeouts.next = NULL;/获取当前任务的优先级err = OSTaskQuery(OS_PRIO_SELF,&curr_task_pcb);curr_prio = curr_task_pcb.OSTCBPrio;offset = curr_prio - LWIP_START_PRIO;/判断当前任务优先级是不是tcp/ip相关任务,优先级5-9if(offset = LWIP_TASK_MAX)return &null_timeouts;return &lwip_timeoutsoffset;注意:移植代码时曾在本函数有一个bug。把上面函数中的OS_TCB curr_task_tcb定义成了全局变量,使本函数成为了一个不可重入函数.在进行如下测试时发现了这个bug。开发板上设置的ip地址是5。在windows的dos窗口内运行ping 5 l 2000 t,不间断用长度为2000的数据报进行ping测试,同时使用tftp客户端软件给5下载一个十几兆程序,同时再使用telnet连接5端口7(echo端口),往该端口写数测试echo功能。在运行一段时间以后,开发板进入不再响应,经过长时间的分析才发现是因为在低优先级任务运行sys_arch_timeouts()时被高优先级任务打断改写了curr_task_tcb的值,从而使sys_arch_timeouts返回的指针错误,进而导致系统死锁。函数sys_timeout给当前任务增加一个定时事件:void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)struct sys_timeouts *timeouts;struct sys_timeout *timeout, *t;timeout = memp_malloc(MEMP_SYS_TIMEOUT);/为定时事件分配内存if (timeout = NULL) return;timeout-next = NULL;timeout-h = h;timeout-arg = arg;timeout-time = msecs;timeouts = sys_arch_timeouts();/返回当前任务定时事件链表起始指针if (timeouts-next = NULL) /如果链表为空直接增加该定时事件timeouts-next = timeout;return;/如果链表不为空,对定时事件进行排序.注意定时事件中的time存储的是本事件 /时间相对于前一事件的时间的差值if (timeouts-next-time msecs) timeouts-next-time -= msecs;timeout-next = timeouts-next;timeouts-next = timeout; else for(t = timeouts-next; t != NULL; t = t-next) timeout-time -= t-time;if (t-next = NULL |t-next-time timeout-time) if (t-next != NULL) t-next-time -= timeout-time;timeout-next = t-next;t-next = timeout;break;函数sys_untimeout从当前任务定时事件链表中删除一个定时事件void sys_untimeout(sys_timeout_handler h, void *arg)struct sys_timeouts *timeouts;struct sys_timeout *prev_t, *t;timeouts = sys_arch_timeouts();/返回当前任务定时事件链表起始指针if (timeouts-next = NULL)/如果链表为空直接返回return;/查找对应定时事件并从链表中删除。for (t = timeouts-next, prev_t = NULL; t != NULL; prev_t = t, t = t-next)if (t-h = h) & (t-arg = arg)/* We have a match */* Unlink from previous in list */if (prev_t = NULL)timeouts-next = t-next;elseprev_t-next = t-next;/* If not the last one, add time of this one back to next */if (t-next != NULL)t-next-time += t-time;memp_free(MEMP_SYS_TIMEOUT, t);return;return;2.2.4“mbox”的实现:(1)mbox的创建sys_mbox_t sys_mbox_new(void) u8_tucErr;PQ_DESCRpQDesc; /从消息队列内存分区中得到一个内存块pQDesc = OSMemGet( pQueueMem, &ucErr ); if( ucErr = OS_NO_ERR ) /创建一个消息队列pQDesc-pQ=OSQCreate(&(pQDesc-pvQEntries0),MAX_QUEUE_ENTRIES );if( pQDesc-pQ != NULL ) return pQDesc; return SYS_MBOX_NULL; (2)发一条消息给”mbox”const void * const pvNullPointer = 0xffffffff;void sys_mbox_post(sys_mbox_t mbox, void *data)INT8U err;if( !data ) data = (void*)&pvNullPointer;err= OSQPost( mbox-pQ, data);在ucos中,如果OSQPost (OS_EVENT *pevent, void *msg)中的msg=NULL 会返回一条OS_ERR_POST_NULL_PTR错误。而在lwip中会调用sys_mbox_post(mbox,NULL)发送一条空消息,我们在本函数中把NULL变成一个常量指针0xffffffff。(3)从”mbox”中读取一条消息#define SYS_ARCH_TIMEOUT 0xffffffffvoid sys_mbox_fetch(sys_mbox_t mbox, void *msg)u32_t time;struct sys_timeouts *timeouts;struct sys_timeout *tmptimeout;sys_timeout_handler h;void *arg;again:timeouts = sys_arch_timeouts();/返回当前任务定时事件链表起始指针if (!timeouts | !timeouts-next) /如果定时事件链表为空sys_arch_mbox_fetch(mbox, msg, 0);/无超时等待消息 else if (timeouts-next-time 0) /如果超时事件链表不为空,而且第一个超时事件的time !=0/带超时等待消息队列,超时时间等于超时事件链表中第一个超时事件的time,time = sys_arch_mbox_fetch(mbox, msg, timeouts-next-time);/在后面分析中可以看到sys_arch_mbox_fetch调用了ucos中的OSQPend系统调/用从消息队列中读取消息./如果”mbox”消息队列不为空,任务立刻返回,否则任务进入阻塞态./需要重点说明的是sys_arch_mbox_fetch的返回值time:如果sys_arch_mbox_fetch/因为超时返回,time=SYS_ARCH_TIMEOUT,/如果sys_arch_mbox_fetch因为收到消息而返回,/time = 收到消息时刻的时间-执行sys_arch_mbox_fetch时刻的时间,单位是毫秒/由于在ucos中任务调用OSQPend系统调用进入阻塞态,到收到消息重新开始执行/这段时间没有记录下来,所以我们要简单修改ucos的源代码.(后面我们会看到). else /如果定时事件链表不为空,而且第一个定时事件的time =0,表示该事件的定时 /时间到time = SYS_ARCH_TIMEOUT;if (time = SYS_ARCH_TIMEOUT) /一个定时事件的定时时间到tmptimeout = timeouts-next;timeouts-next = tmptimeout-next;h = tmptimeout-h;arg = tmptimeout-arg;memp_free(MEMP_SYS_TIMEOUT, tmptimeout);/从内存中释放该定时事件,并执行该定时事件中的函数if (h != NULL) h(arg);/因为定时事件中的定时时间到或者是因为sys_arch_mbo_fetch超时到而执行到/这里,返回本函数开头重新等待mbox的消息goto again; else /如果sys_arch_mbox_fetch无超时收到消息返回/则刷新定时事件链表中定时事件的time值.if (time next-time) timeouts-next-time -= time; else timeouts-next-time = 0;u32_tsys_arch_mbox_fetch(sys_mbox_t mbox, void *data, u32_t timeout)u32_tucErr;u16_t ucos_timeout;/在 lwip中 ,timeout的单位是ms/ 在ucosII ,timeout 的单位是timer tick ucos_timeout = 0; if(timeout != 0) ucos_timeout = (timeout )*( OS_TICKS_PER_SEC/1000); if(ucos_timeout 65535)ucos_timeout = 65535;/如果data!=NULL就返回消息指针,if(data != NULL)*data = OSQPend( mbox-pQ, (u16_t)ucos_timeout, &ucErr );elseOSQPend(mbox-pQ,(u16_t)ucos_timeout,&ucErr);/这里修改了ucos中的OSQPend系统调用, /原来的void*OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)/ err的返回值只有两种:收到消息就返回OS_NO_ERR,超时则返回OS_TIMEOUT/这里先将err从8位数据改变成了16位数据 OSQPend(*pevent,timeout, INT16U *err)/重新定义了OS_TIMEOUT/在ucos中原有#define OS_TIMEOUT 20/改为 #defineOS_TIMEOUT-1/err返回值的意义也改变了,如果超时返回OS_TIMEOUT/ 如果收到消息,则返回OSTCBCur-OSTCBDly修改部分代码如下/if (msg != (void *)0) /* Did we get a message?*/ OSTCBCur-OSTCBMsg = (void *)0;/ OSTCBCur-OSTCBStat= OS_STAT_RDY;/ OSTCBCur-OSTCBEventPtr = (OS_EVENT *)0;/ *err = OSTCBCur-OSTCBDly;/ zhangzs 2003.12.12/OS_EXIT_CRITICAL();/ return (msg);/* Return message received */关于ucos的OSTBCur-OSTCBDly的含义请查阅ucos的书籍if( ucErr = OS_TIMEOUT ) timeout = SYS_ARCH_TIMEOUT; else if(*data = (void*)&pvNullPointer ) *data = NULL;/单位转换,从ucos tick-mstimeout = (ucos_timeout -ucErr)*(1000/ OS_TICKS_PER_SEC);return timeout;semaphone的实现和mbox类似,这里就不再重复了实验十一、嵌入式网络协议telnet实验一、实验目的 1掌握telnet工作原理;2掌握基于lwip的嵌入式网络编程的基本方法;3掌握如何在嵌入式平台上建立简单的telnet;二、实验内容 了解telnet的工作原理,学习网络编程的基本步骤,学习使用lwip的几个常用API的使用方法。基于lwip和uC/OS-II建立一个telnet,通过PC访问之。三、预备知识 1ADS 1.2 集成开发环境的使用。2网络编程的基本步骤。3ARM应用程序的框架结构。 4Lwip函数的使用。5telnet的工作方法。四、实验设备及工具 硬件:S3C44B0X嵌入式开发板、用于ARM7TDMI的JTAG仿真器、PC机Pentumn100以上、串口线。软件:PC机操作系统win98、Win2000或WinXP、ARM ADS 1.2集成开发环境、仿真器驱动程序、串口调试助手、实验原理及说明 五、实验原理 1 Socket编程基础1.1什么是socket所谓socket通常也称作套接字,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过套接字向网络发出请求或者应答网络请求。在一个程序中使用socket需要执行4个步骤:1) 分配空间和初始化;2) 连接;3) 传送数据4) 关闭。在具体实现时,客户端和服务器端又不是完全一样的,下面是网络编程的服务器端和客户端具体的实现步骤:1.2 lwip中常用的API:本实验目的是实现Http Server,关注的是服务器端的编程。对应与上面服务器端编程的各个步骤,lwip提供的函数有l struct netconn *netconn_new(enum netconn_type t)用于建立连接。l err_t netconn_delete(struct netconn *conn)用于删除连接。l err_t netconn_bind(struct netconn *conn, struct ip_addr *addr,u16_t port)绑定连接。l err_t netconn_listen(struct netconn *conn)用于监听。l struct netconn *netconn_accept(struct netconn *conn)处理接收到的客户端信号,返回一个新连接专门处理该客户端和服务器端之间通信。l struct netbuf *netconn_recv(struct netconn *conn)用于接受数据。l err_t netconn_send(struct netconn *conn, struct netbuf *buf)用于发送数据。2. Telnet工作原理简述(1)远程登录 Telnet服务虽然也属于客户机/服务器模型的服务,但它更大的意义在于实现了基于Telnet协议的远程登录(远程交互式计算),那么就让我们来认识一下远程登录。 A 远程登陆的基本概念 先来看看什么叫登录:分时系统允许多个用户同时使用一台计算机,为了保证系统的安全和记帐方便,系统要求每个用户有单独的帐号作为登录标识,系统还为每个用户指定了一个口令。用户在使用该系统之前要输入标识和口令,这个过程被称为登录。 远程登陆是指用户使用Telnet命令,使自己的计算机暂时成为远程主机的一个仿真终端的过程。仿真终端等效于一个非智能的机器,它只负责把用户输入的每个字符传递给主机,再将主机输出的每个信息回显在屏幕上。 B 远程登陆的产生及发展 我们可以先构想一个提供远程文字编辑的服务,这个服务的实现需要一个接受编辑文件请求和数据的服务器以及一个发送此请求的客户机。客户机将建立一个从本地机到服务器的TCP连接,当然这需要服务器的应答,然后向服务器发送键入的信息(文件编辑信息),并读取从服务器返回的输出。以上便是一个标准而普通的客户机/服务器模型的服务。 似乎有了客户机/服务器模型的服务,一切远程问题都可以解决了。然而实际并非你想象的那样简单,如果我们仅需要远程编辑文件,那么刚才所构想的服务完全可以胜任,但假如我们的要求并不是这么简单,我们还想实现远程用户管理,远程数据录入,远程系统维护,想实现一切可以在远程主机上实现的操作,那么我们将需要大量专用的服务器程序并为每一个可计算服务都使用一个服务器进程,随之而来的问题是:远程机器会很快对服务器进程应接不暇,并淹没在进程的海洋里(我们在这里排除最专业化的远程机器)。 那么有没有办法解决呢?当然有,我们可以用远程登录来解决这一切。我们允许用户在远地机器上建立一个登录会话,然后通过执行命令来实现更一般的服务,就像在本地操作一样。这样,我们便可以访问远地系统上所有可用的命令,并且系统设计员不需提供多个专用地服务器程序。 问题发展到这里好像前途一片光明了,用远程登录总应该解决问题了吧,但要实现远程登陆并不简单。不考虑网络设计的计算机系统期望用户只从直接相连的键盘和显示器上登录,在这种机器上增加远程登陆功能需要修改机器的操作系统,这是极其艰巨也是我们尽量避免的。因此我们应该集中力量构造远程登陆服务器软件,虽然这样也是比较困难的。为什么说这样做也比较困难呢? 举个例子来说:一般,操作系统会为一些特殊按键分配特殊的含义,比如本地系统将Ctrl+C解释为:终止当前运行的命令进程。但假设我们已经运行了远程登陆服务器软件,Ctrl+C也有可能无法被传送到远地机器,如果客户机真的将Ctrl+C传到了远地机器,那么Ctrl+C这个命令有可能不能终止本地的进程,也就是说在这里很可能会产生混乱。而且这仅仅是遇到的难题之一。 但尽管有技术上的困难,系统编程人员还是设法构造了能够应用于大多数操作系统的远程登陆服务器软件,并构造了充当客户机的应用软件。通常,客户机软件取消了除一个键以外的所有键的本地解释,并将这些本地解释相应的转换成远地解释,这就使得客户机软件与远地机器的交互,就如同坐在远程主机面前一样,从而避免了上述所提到的混乱。而那个唯一例外的键,可以使用户回到本地环境。 将远程登陆服务器设计为应用级软件,还有另一个要求,那就是需要操作系统提供对伪终端(pseudo terminal)的支持。我们用伪终端描述操作系统的入口点,它允许像Telnet服务器一样的程序向操作系统传送字符,并且使得字符像是来自本地键盘一样。只有使用这样的操作系统,才能将远程登陆服务器设计为应用级软件(比如Telnet服务器软件),否则,本地操作系统和远地系统传送将不能识别从对方传送过来的信息(因为它们仅能识别从本地键盘所键入的信息),远程登陆将宣告失败。 将远程登陆服务器设计为应用级软件虽然有其显著的优点:比将代码嵌入操作系统更易修改和控制服务器。但其也有效率不高的缺点(后面的内容将会给予解释),好在用户键入信息的速率不高,这种设计还是可以接受的。 C 远程登录的工作过程 使用Telnet协议进行远程登陆时需要满足以下条件:在本的计算机上必须装有包含Telnet协议的客户程序;必须知道远程主机的Ip地址或域名;必须知道登录标识与口令。 Telnet远程登录服务分为以下4个过程: 1)本地与远程主机建立连接。该过程实际上是建立一个TCP连接,用户必须知道远程主机的Ip地址或域名; 2)将本地终端上输入的用户名和口令及以后输入的任何命令或字符以NVT(Net Virtual Terminal)格式传送到远程主机。该过程实际上是从本地主机向远程主机发送一个IP数据报; 3)将远程主机输出的NVT格式的数据转化为本地所接受的格式送回本地终端,包括输入命令回显和命令执行结果; 4)最后,本地终端对远程主机进行撤消连接。该过程是撤销一个TCP连接。 上面的内容只是讨论了远程登陆最基本的东西,其中的复杂和编程人员的艰辛是我们难以想象的,不知道你在舒服的使用Telnet的同时,是否想到了这些! (2)Telnet协议 我们知道Telnet服务器软件是我们最常用的远程登录服务器软件,是一种典型的客户机/服务器模型的服务,它应用Telnet协议来工作。那么,什么是Telnet协议?它都具备哪些特点呢? A 基本内容 Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议。应用Telnet协议能够把本地用户所使用的计算机变成远程主机系统的一个终端。它提供了三种基本服务: 1)Telnet定义一个网络虚拟终端为远的系统提供一个标准接口。客户机程序不必详细了解远的系统,他们只需构造使用标准接口的程序; 2)Telnet包括一个允许客户机和服务器协商选项的机制,而且它还提供一组标准选项; 3)Telnet对称处理连接的两端,即Telnet不强迫客户机从键盘输入,也不强迫客户机在屏幕上显示输出。 B 适应异构 为了使多个操作系统间的Telnet交互操作成为可能,就必须详细了解异构计算机和操作系统。比如,一些操作系统需要每行文本用ASCII回车控制符(CR)结束,另一些系统则需要使用ASCII换行符(LF),还有一些系统需要用两个字符的序列回车-换行(CR-LF);再比如,大多数操作系统为用户提供了一个中断程序运行的快捷键,但这个快捷键在各个系统中有可能不同(一些系统使用CTRL+C,而另一些系统使用ESCAPE)。如果不考虑系统间的异构性,那么在本地发出的字符或命令,传送到远地并被远地系统解释后很可能会不准确或者出现错误。因此,Telnet协议必须解决这个问题。 为了适应异构环境,Telnet协议定义了数据和命令在Internet上的传输方式,此定义被称作网络虚拟终端NVT(Net Virtual Terminal)。它的应用过程如下: 对于发送的数据:客户机软件把来自用户终端的按键和命令序列转换为NVT格式,并发送到服务器,服务器软件将收到的数据和命令,从NVT格式转换为远地系统需要的格式; 对于返回的数据:远地服务器将数据从远地机器的格式转换为NVT格式,而本地客户机将将接收到的NVT格式数据再转换为本地的格式。 对于NVT格式的详细定义,有兴趣的朋友可以去查找相关资料。 C 传送远地命令 我们知道绝大多数操作系统都提供各种快捷键来实现相应的控制命令,当用户在本地终端键入这些快捷键的时候,本地系统将执行相应的控制命令,而不把这些快捷键作为输入。那么对于Telnet来说,它是用什么来实现控制命令的远地传送呢? Telnet同样使用NVT来定义如何从客户机将控制功能传送到服务器。我们知道USASCII字符集包括95个可打印字符和33个控制码。当用户从本地键入普通字符时,NVT将按照其原始含义传送;当用户键入快捷键(组合键)时,NVT将把它转化为特殊的ASCII字符在网络上传送,并在其到达远地机器后转化为相应的控制命令。将正常ASCII字符集与控制命令区分主要有两个原因: 1)这种区分意味着Telnet具有更大的灵活性:它可在客户机与服务器间传送所有可能的ASCII字符以及所有控制功能; 2)这种区分使得客户机可以无二义性的指定信令,而不会产生控制功能与普通字符的混乱。 D 数据流向 上面我们提到过将Telnet设计为应用级软件有一个缺点,那就是:效率不高。这是为什么呢?下面给出Telnet中的数据流向: 数据信息被用户从本地键盘键入并通过操作系统传到客户机程序,客户机程序将其处理后返回操作系统,并由操作系统经过网络传送到远地机器,远地操作系统将所接收数据传给服务器程序,并经服务器程序再次处理后返回到操作系统上的伪终端入口点,最后,远地操作系统将数据传送到用户正在运行的应用程序,这便是一次完整的输入过程;输出将按照同一通路从服务器传送到客户机。 因为每一次的输入和输出,计算机将切换进程环境好几次,这个开销是很昂贵的。还好用户的键入速率并不算高,这个缺点我们仍然能够接受。 E 强制命令 我们应该考虑到这样一种情况:假设本地用户运行了远地机器的一个无休止循环的错误命令或程序,且此命令或程序已经停止读取输入,那么操作系统的缓冲区可能因此而被占满,如果这样,远地服务器也无法再将数据写入伪终端,并且最终导致停止从TCP连接读取数据,TCP连接的缓冲区最终也会被占满,从而导致阻止数据流流入此连接。如果以上事情真的发生了,那么本地用户将失去对远地机器的控制。 为了解决此问题,Telnet协议必须使用外带信令以便强制服务器读取一个控制命令。我们知道TCP用紧急数据机制实现外带数据信令,那么Telnet只要再附加一个被称为数据标记(date mark)的保留八位组,并通过让TCP发送已设置紧急数据比特的报文段通知服务器便可以了,携带紧急数据的报文段将绕过流量控制直接到达服务器。作为对紧急信令的相应,服务器将读取并抛弃所有数据,直到找到了一个数据标记。服务器在遇到了数据标记后将返回正常的处理过程。 F 选项协商 由于Telnet两端的机器和操作系统的异构性,使得Telnet不可能也不应该严格规定每一个telnet连接的详细配置,否则将大大影响Telnet的适应异构性。因此,Telnet采用选项协商机制来解决这一问题。 Telnet选项的范围很广:一些选项扩充了大方向的功能,而一些选项制涉及一些微小细节。例如:有一个选项可以控制Telnet是在半双工还是全双工模式下工作(大方向);还有一个选项允许远地机器上的服务器决定用户终端类型(小细节)。 Telnet选项的协商方式也很有意思,它对于每个选项的处理都是对称的,即任何一端都可以发出协商申请;任何一端都可以接受或拒绝这个申请。另外,如果一端试图协商另一端不了解的选项,接受请求的一端可简单的拒绝协商。因此,有可能将更新,更复杂的Telnet客户机服务器版本与较老的,不太复杂的版本进行交互操作。如果客户机和服务器都理解新的选项,可能会对交互有所改善。否则,它们将一起转到效率较低但可工作的方式下运行。所有的这些设计,都是为了增强适应异构性,可见Telnet的适应异构性对其的应用和发展是多么重要。3. Telnet程序大致流程下面是建立Telnet的主要代码【建立连接,开始监听】s
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 车载油卡开户变更流程说明
- 企业项目预算编制与管理手册
- 科技成果转化项目管理方案
- 建筑钢筋工程监理流程与验收标准
- 心理健康知识宣传电子资料模板
- 建筑施工安全检查标准与执行手册
- 一年级下册语文期末复习规划
- 基坑监测方案设计指导手册
- 小学英语课后辅导效果评估报告
- 物流仓库安全管理岗位职责及考核方案
- 长期照护师技能操作考核试卷及答案
- 街道管理考试题库及答案
- 2025年执业药师之《药事管理与法规》题库附参考答案详解(培优)
- 2025年企业管理人员能力考试试题及答案
- 统编语文(2024)二年级上册识字5《去外婆家》课件
- 2025年6月浙江省高考化学试卷真题(含答案及解析)
- (正式版)DB15∕T 3226-2023 《液化天然气单位产品电耗限额》
- 物权编善意取得制度解读
- 静脉采血业务学习
- 2025年高考政治总复习高中三年必考基础知识复习汇编资料(必背版)
- 保障性租赁住房房屋维修保养方案
评论
0/150
提交评论