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等。

  1. [root@Kendo ~]# ls -l /dev/ttyS*
  2. crw-rw---- 1 root uucp 4, 64 Jan  8 13:39 /dev/ttyS0
  3. crw-rw---- 1 root uucp 4, 65 Jan  8 13:39 /dev/ttyS1
  4. crw-rw---- 1 root uucp 4, 66 Jan  8 13:39 /dev/ttyS2
  5. 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进行写操作。

作为一个测试例子,在控制台终端下,运行命令:

  1. #echo "write to ttyS0" > /dev/ttyS0

复制代码

在串行端口终端中可以看到输出:

  1. # write to ttyS0

复制代码

3、控制终端(/dev/tty) 
控制终端并不面对设备,而是面对进程,关于这个概念,《Unix环境高级编程》第9章有详细论述。

二、从终端登录简述(古代的登陆方式)

Linux系统引导的时候,会运行init进程,它会执行/etc/inittab(这跟具体的init类型有关,我使用了busybox的init,但其本质是一样的):

  1. [root@SkyNet ~]# cat /etc/inittab
  2. ::sysinit:/etc/init.d/rcS
  3. ::respawn:/sbin/getty 9600 ttyS0

复制代码

它会调用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的命名方式如下:

  1. M: p q r s t u v w x y z a b c d e 共16 个
  2. N: 0 1 2 3 4 5 6 7 8 9 a b c d e f 共16 个

复制代码

这样,默认支持最大是256个。

任何写入到伪终端主设备的输入,都会作为伪终端从设备的输入,反之亦然。类似于管道,如下图:
 
一个典型的伪终端进程结构如下图:
 
这张图的关键在于:如果把伪终端从设备想像为传统的终端设备,把主设备看成进程读写数据的一个“接口”,那么它的工作原理,就跟传统终端一样了。

上述只是一个本地进程,把网络引入进来,对应到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而言,在

  1. Device Drivers  --->
  2. Character devices  --->
  3. [*] Legacy (BSD) PTY support
  4. (256) Maximum number of legacy PTY in use

复制代码

可以设定。应该将它调整到足够地大,以供支持应用。同时,/dev目录下,应该有相应的设备文件:

  1. #ls -l /dev/ptyp*
  2. crw-r--r--    1 root     root       2,   0 Dec 18 05:36 /dev/ptyp0
  3. crw-r--r--    1 root     root       2,   1 Dec 18 05:36 /dev/ptyp1
  4. crw-r--r--    1 root     root       2,   2 Dec 18 05:36 /dev/ptyp2
  5. crw-r--r--    1 root     root       2,   3 Dec 18 05:36 /dev/ptyp3

复制代码

  1. #ls -l /dev/ttyp*
  2. crw-------    1 root     root       3,   0 Dec 18 05:36 /dev/ttyp0
  3. crw-------    1 root     root       3,   1 Dec 18 05:36 /dev/ttyp1
  4. crw-r--r--    1 root     root       3,   2 Dec 18 05:36 /dev/ttyp2
  5. crw-------    1 root     root       3,   3 Dec 18 05:36 /dev/ttyp3

复制代码

这样命令方式,并且要指定数量的方式实在是让人郁闷。因为它有一个数量上限的问题,最大256。

为了解决这个问题,Linux引入了一种新的命名方式:UNIX98_PTYS。关于这个东东,内核是这样解释的:

  1. Linux has traditionally used the BSD-like names /dev/ptyxx for
  2. masters and /dev/ttyxx for slaves of pseudo terminals. This scheme
  3. has a number of problems. The GNU C library glibc 2.1 and later,
  4. however, supports the Unix98 naming standard: in order to acquire a
  5. pseudo terminal, a process opens /dev/ptmx; the number of the pseudo
  6. terminal is then made available to the process and the pseudo
  7. terminal slave can be accessed as /dev/pts/<number>. What was
  8. traditionally /dev/ttyp2 will then be /dev/pts/2, for example.
  9. All modern Linux systems use the Unix98 ptys.  Say Y unless
  10. you're on an embedded system and want to conserve memory.

复制代码

这样,可以通过访问/dev/ptmx设备文件的形式,来访问伪终端设备了,例如我的PPTP服务器,当有五个用户拨入后:

  1. # ls -l /dev/pts/
  2. crw-------    1 root     root     136,   0 Jan  8 12:18 0
  3. crw-------    1 root     root     136,   1 Jan  8 08:08 1
  4. crw-------    1 root     root     136,   2 Jan  8 14:10 2
  5. crw-------    1 root     root     136,   3 Jan  8 14:27 3
  6. crw-------    1 root     root     136,   4 Jan  8 08:29 4

复制代码

linux的终端,网络虚拟终端,伪终端(转)的更多相关文章

  1. linux tty终端个 pts伪终端 telnetd伪终端

    转:http://blog.sina.com.cn/s/blog_735da7ae0102v2p7.html 终端tty.虚拟控制台.FrameBuffer的切换过程详解 Framebuffer Dr ...

  2. linux的终端,网络虚拟终端,伪终端(转)

    转自http://www.xuebuyuan.com/877887.html 2013年09月07日 ⁄ 综合 ⁄ 共 4047字 ⁄ 字号 小 中 大 ⁄ 评论关闭 Linux上许多网络服务应用,如 ...

  3. Linux 的伪终端的基本原理 及其在远程登录(SSH,telnet等)中的应用

    本文介绍了linux中伪终端的创建,介绍了终端的回显.行缓存.控制字符等特性,并在此基础上解释和模拟了telnet.SSH开启远程会话的过程. 一.轻量级远程登录 之前制作的一块嵌入式板子,安装了嵌入 ...

  4. Linux 伪终端(pty)

    通过<Linux 终端(TTY)>一文我们了解到:我们常说的终端分为终端 tty1-6 和伪终端.使用 tty1-6 的情况一般为 Linux 系统直接连了键盘和显示器,或者是使用了 vS ...

  5. Linux 串行终端,虚拟终端,伪终端,控制终端,控制台终端的理解

    转自Linux 串行终端,虚拟终端,伪终端,控制终端,控制台终端的理解 终端:输入和输出设备(键盘 + 显示器). 串行终端:与机器的串口对应,每一个串口对应一个串行终端,串口对应的是物理终端. 虚拟 ...

  6. 关于Unix/Linux的终端、伪终端、控制台和shell

    历史是什么:是过去传到将来的回声,是将来对过去的反映. ——雨果(法)<笑面人> 阅读本文大概需要花费你15分钟 文章导航: 计算机的发展 UNIX系统的诞生 UNIX系统的发展 终端与控 ...

  7. linux下强制退出指定用户开启的伪终端

    一.环境 发行版:Ubuntu 18.04.1 LTS 代号:bionic 内核版本:4.15.0-30-generic 二.背景 每次通过ssh登陆服务器,但是超时后自动断开了与服务器的连接,因此在 ...

  8. 终端、虚拟终端、shell、控制台、tty的区别

    终端与控制台的区别? 最近开始接触Linux,终端.虚拟终端.shell.控制台.tty等概念让我很混乱,有必要认识清楚. 今天看到有人问终端和控制台的区别,而且这个问题比较有普遍性,因此想抽出一点时 ...

  9. Linux下使命令不受终端断开的影响,保持在后台运行的几种方法及原理

    摘自https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/ 记录一下Linux下使命令不受终端断开的影响,保持在后台运行的几个方法及其原理.当用 ...

随机推荐

  1. DEDECMS中,arclist标签

    文档列表  dede:arclist 标签: {dede:arclist flag='h' typeid='' row='' col='' titlelen='' infolen='' imgwidt ...

  2. Call与Apply

    1.前言 ECMAscript中提供了两个方法(call,apply)用于改变对象内部的this指针,它们两个的作用都是一样的,但是传递的参数有点不大相同. 它们的大概语法为: call(this, ...

  3. Mac下使用Web服务器性能/压力测试工具webbench、ab、siege

    Web开发,少不了的就是压力测试,它是评估一个产品是否合格上线的基本标准,下面我们来一一剖析他们的使用方式. 测试前,前面先把系统的端口限制数改大,看看Mac下面的默认限制 ulimit -a ope ...

  4. c#的协变和逆变

    关于协变和逆变要从面向对象继承说起.继承关系是指子类和父类之间的关系:子类从父类继承,所以子类的实例也就是父类的实例.比如说Animal是父类,Dog是从Animal继承的子类:如果一个对象的类型是D ...

  5. 关于canvas中的jquery

    关于h5,相比前端的同事们都很了解了吧!h5里面有个canvas,现在用的蛮火.但是canvas里面的代码确实是有点繁多,特别是要对于图形做什么操作的时候...我昨天无意间发现了一个canvas的插件 ...

  6. ES6学习笔记(一)

    1.let命令 基本用法 ES6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. { let a = 10; var b = 1; } a / ...

  7. [Linux]学习笔记(1)

    说到Linux就不得不提UNIX,因为Linux是从UNIX系统发展来的,两系统极为相似,可以在UNIX操作系统上使用的功能都可以在Linux上使用,只可能有少许的差异: UNIX系统中所有的东西都是 ...

  8. scala知识点(二)

    Scala允许使用三个引号来进行多行字符引用:(引自) val longString = """Line 1 Line Line """; ...

  9. http中的KeepAlive

    为什么要使用KeepAlive? 终极的原因就是需要加快客户端和服务端的访问请求速度.KeepAlive就是浏览器和服务端之间保持长连接,这个连接是可以复用的.当客户端发送一次请求,收到相应以后,第二 ...

  10. android studio 打开github开源代码

    1.最近下载的开源代码全是github来的,一直用eclipse开发,对于android studio来说是全新的 2.在eclipse导入一个工程那是so easy, import选择一下就可以. ...