Answers:
恭喜,您刚刚意识到端口和协议没有彼此直接连接,从而深入研究了网络层的概念。就像其他人所说的,可以使用telnet连接到任何TCP端口。但是,要了解为什么这样做是可能的,您需要对网络层有所了解。如果您曾经听说过OSI 7层模型,则可以使用telnet连接到另一个端口。尽管在Internet上,他们只关心其中的4个层及其称为Internet协议套件的Internet。没有网络层,每个程序不仅需要了解自己的协议,而且还必须定义自己的IP寻址方案和端口系统,这意味着每个路由器都需要了解如何路由这些方案,并且不同的协议会很多。难以学习和诊断。简而言之,如果没有分层,互联网将无法正常运行。
您所关心的是传输层和应用程序层。在传输层,我们拥有Internet协议,例如TCP和UDP,每个协议的端口号范围从1到65535。在应用程序层,我们有HTTP,SMTP和DNS等协议。通常,每个定义协议的Internet标准文档都指定该协议默认应使用的默认TCP或UDP端口。例如用于HTTP的TCP端口80,用于SMTP的TCP端口25,用于DNS的UDP端口53和用于Telnet的TCP端口23。telnet程序实际上使用TELNET协议,这是一个标准协议,但按照当前的标准,大多数都是古老的。由于其协议序列是由8位字符组成的,因此与使用ASCII,人类可见字词的其他更现代的协议(例如HTTP和SMTP)(例如GET,POST,HELO,LOGIN,等等
由于telnet协议通常不可见,因此它是一种不错的工具,用于连接到其他TCP端口并允许用户手动键入协议。一些网络管理员使用此技术来诊断服务器问题。但是,由于telnet程序仍具有其自己的协议,并且有时可能会发送额外的数据位,因此您仍然会在使用此技术时遇到问题。使用telnet时,您实际上是在应用程序层和传输层“建立连接”。碰巧其他应用程序层协议对于大多数诊断也可以正常工作,并且不会干扰telnet协议。有一个更好的程序可以通过nc(Net Cat。它通过使用cat命令的基于网络的版本来命名)来实现。
$ nc www.stackexchange.com 80
nc程序不讲任何应用程序层协议,与它建立连接时,仅在Internet层(IP地址)和传输层(TCP或UDP)上“建立连接”。这意味着您可以控制使用哪种应用程序层协议。几乎所有东西都是公平的游戏,甚至是二进制协议。这也使您可以做有用的事情,例如传输文件而不会损坏文件,并侦听端口上的传入流量:
nc -l 9000 < movie.mp4 (Your friend runs this)
nc friends.computer.hostname 9000 > movie.mp4 (you run this)
然后,根本不使用任何应用程序层协议(例如FTP)通过网络传输movie.mp4。该应用程序协议实际上是您的朋友告诉您,它们已准备就绪,可以运行您的命令。
nc还可以处理UDP数据包和UNIX域套接字。用它来听也可能很有趣。
nc -l 12345
现在,在Web浏览器中,访问http:// localhost:12345 /,在nc会话中,您应该看到浏览器的GET / HTTP/1.1
请求。此时,您可以输入内容并按Ctrl-D
,它应该以纯文本形式显示在浏览器中(如果要显示HTML,则必须将其发送回正确的HTTP协议响应以及HTML代码)。
有时,本机说一种协议(例如HTTP)的程序可以连接到用于其他协议的其他端口。通常,您不能再在GUI浏览器中执行此操作了,因为它们限制了它们无法连接到某些端口,但是如果您使用curl等程序来连接到端口25(用于发送邮件的SMTP),则可能会看到几个有关违反协议的错误。
$ curl yourispsmtpserverhost.com:25
220 yourispsmtpserverhost.com ESMTP Postfix
221 2.7.0 Error: I can break rules, too. Goodbye.
发生这种情况是因为curl通常使用HTTP协议,因此在建立TCP握手后,它将开始发送数据,如下所示:
GET / HTTP/1.1
Host: yourispsmtpserverhost.com:25
User-agent: curl
但是SMTP服务器期望的是SMTP,它更像是这样:
HELO myhomecomputername.local
此时服务器将发回其标识行:
250 yourispsmtpserverhost.com
因此,您会看到没有什么可以阻止curl与SMTP服务器建立传输层连接,只是无法说出协议。但是您可以使用诸如telnet或更优选的nc之类的程序自己说出协议。
curl
需要一个-v
参数来显示详细的在OS X输出
telnet
是可以连接到任何tcp端口的工具。
默认情况下,它连接到telnet端口(23),但是您可以告诉它连接到http端口(80)或smtp端口(25)或其他端口。
但是,您需要知道如何“说出”远程服务器在该端口上侦听的协议。
例如,如果您要获取网站的标题(为了保护罪名,更改了域名等):
$ telnet www.example.com 80
Trying xxx.xxx.xxx.xxx...
Connected to www.example.com.
Escape character is '^]'.
HEAD http://www.example.com/ HTTP/1.0
HTTP/1.1 200 OK
Date: Fri, 30 Oct 2015 09:28:58 GMT
Server: Apache/2.4.17 (Debian)
Last-Modified: Sun, 14 Nov 2010 06:30:26 GMT
ETag: "843-494fd75830480"
Accept-Ranges: bytes
Content-Length: 2115
Vary: Accept-Encoding
Connection: close
Content-Type: text/html
Connection closed by foreign host.
这HEAD
是我在连接中键入的内容。请注意,http协议要求您发送空白行以指示HEAD或GET或任何请求的结尾。这是HEAD请求后的空白行。
两种协议的初始协商都使用文本命令,因此您可以连接并开始输入命令。SMTP 等其他旧协议也是如此,并且长期以来一直使用telnet来排除与相应服务的连接故障。
例如
协议独立于它们进行通信的端口。几乎所有的实现都可以配置为侦听任何端口。
某些协议(例如HTTPS)不使用文本命令进行协商。但是,您可以(通常)连接到服务器侦听的端口,但无济于事。
您的某些理解是正确的,而某些则不是。端口80通常为HTTP保留,但这只是一个约定。任何程序都可以侦听系统上任何打开的端口。如果有一个Web服务器正在监听您要连接的系统上的端口80,则需要使用HTTP与之通信。
telnet
根本不是协议,它是一个程序,可让您将原始文本发送到任何端口上的任何主机。远程主机不知道正在连接什么程序。它所看到的只是发送给它的数据包。任何发送符合远程主机期望的协议的数据包的程序都可以使用,因此您可以telnet
用来通过任何基于文本的协议进行通信。
您沿的方向发送了一些内容GET /path/to/a/file HTTP/1.1
,这是有效的HTTP 1.1命令,外观与Web浏览器发送的请求相同,因此可以正常工作。
telnet
是RFC 854协议。只是普通telnet
客户端telnet
仅在连接时才尝试使用该协议tcp/21
。在手册页中:“当连接到telnet端口以外的端口时,telnet不会尝试telnet协议协商。这使得可以连接到不支持telnet协议的服务而不会造成混乱。协议协商可以通过以下方式强制进行:在端口号前加一个破折号。”
nc(1)
)命令要灵活得多。它可以连接到SSL / TLS加密服务,还可以用作服务器甚至中继数据。