相关文章推荐
坐怀不乱的蚂蚁  ·  python - Why does ...·  1 年前    · 
瘦瘦的蚂蚁  ·  Jira 和 Confluence ...·  1 年前    · 
精明的茶叶  ·  vue按钮点击后禁用-掘金·  1 年前    · 
blog.csdn.net/todd911/article/details/8025540
Linux上许多网络服务应用,如l2tp、pptp、 telnet ,都用到了伪终端。有朋友在问这方面的概念,把偶知道的写下来,以供讨论。
要理解伪终端(Pseudo Terminal),先来看看什么是“终端”(Terminal)。
终端是一种字符型设备,它有多种类型,通常使用tty来简称各种类型的终端设备。
1、串行端口终端(/dev/ttySx)
串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。
这些串行端口所对应的设备名称是/dev/ttyS0、/dev/ttyS1等,分别对应于DOS系统下的COM1、COM2等。
[root@Kendo ~]# ls -l /dev/ttyS*
crw-rw---- 1 root uucp 4, 64 Jan  8 13:39 /dev/ttyS0
crw-rw---- 1 root uucp 4, 65 Jan  8 13:39 /dev/ttyS1
crw-rw---- 1 root uucp 4, 66 Jan  8 13:39 /dev/ttyS2
crw-rw---- 1 root uucp 4, 67 Jan  8 13:39 /dev/ttyS3 2、控制台终端(/dev/ttyn, /dev/console)
在Linux系统中,计算机显示器通常被称为控制台终端(Console)。它仿真了类型为Linux的一种终端(TERM=Linux),
与之相关联的设备文件为:tty0、tty1、tty2……。当用户从控制台上登录时,使用的是tty1。使用Alt+[F1—F6]组合键时,我们就可以切换
到tty2、tty3……上面去。tty1 –tty6等称为虚拟终端,而tty0则是当前所使用虚拟终端的一个别名,系统所产生的信息会发送到该终端上。
因此不管当前正在使用哪个虚拟终端,系统信息都会发送到控制台终端上。用户可以登录到不同的虚拟终端上去,因而可以让系统同时有几
个不同的会话期存在。只有系统或超级用户root可以向/dev/tty0进行写操作。
作为一个测试例子,在控制台终端下,运行命令:
它会调用 getty 在指定波特率上打开ttyS0,即,串行端口终端。打开成功后,stdout,stdin,stderr都被设置到该备上,然后 getty 输出:"login:"之类的提示符,等待用户输入。
当用户键入用户名后, getty 就 执行login程序,类似于:execle("login")。login可以调用getpass()以显示Password:并读入用户口令。并且调用 getpwnam进行口令验证。如果成功,调用类似execle("shell")。这样,登录用户就拥有了一个shell了。
三、伪终端
上述登录过程,对于网络用户来说,却不能完全实用。很显然,网络用户并不需要一个串口,也不需要一个显示器,他需要的是在他的本地显示设备上, 运行Linux的shell。这种网络用户被称为网络虚拟终端。以telnetd为例,它至少应该是这样子的:
图一: telnet 登录假想图
里,这个“某个终设备”,自然不可能是一个实际的物理终端设备,因为压根没有这样的设备。这样,伪终端的概念就被引入进来了。伪终端设备是一种特殊的终端 驱动设备, 它并不驱动某个物理设备,而是用来将终端的输出定向到应用程序中进行处理。伪终端设备之所以存在是为了提供在程序控制下的一种模拟串行终端行为的方法。
伪终端与前面说的终端在表现形式上,最大的不同,就是它总是成对出现,而不是单一的一个。它分为“伪终端主设备(/dev/ptyMN)”和“伪终端从设备”。(/dev/ttyMN)。其中,M与N的命名方式如下:
M: p q r s t u v w x y z a b c d e 共16 个
N: 0 1 2 3 4 5 6 7 8 9 a b c d e f 共16 个 这张图的关键在于:如果把伪终端从设备想像为传统的终端设备,把主设备看成进程读写数据的一个“接口”,那么它的工作原理,就跟传统终端一样了。
上述只是一个本地进程,把网络引入进来,对应到telnetd上面来,应该是下面这个样子:
同样的登录方式,就变成了这样:
1、如果某人在网上使用 telnet 程序连接到本地服务器,则telnetd程序就可能会开始连接到设备ptyp2(m2)上(一个伪终端主设备上)。
2、telnetd产生一个子进程,进行 getty 程序,其打开一个对应的从设备对应的ttyp2(s2),并设置stdin\stdout\stderr;
3、telnetd通过内核tcp/ip协议栈从远端获取了一个字符时,该字符就会通过m2、s2传递给 getty 程序,而 getty 程序就会通过s2、m2和telnetd程序往网络上返回”login:”字符串信息;
4、这样,登录程序与telnetd程序就通过“伪终端”进行通信;
四、伪终端的数量
对于Linux下的应用而言,知道伪终端的数量是一个关键的东东,或者它直接决定了最大支持用户数,例如PPTP VPN的应用。(没有多余的可以供打开的
伪终端设备了)。
对于2.6.X而言,在