提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、场景
- 二、介绍
- 1.测试端口
- 2.访问百度
- 3. 简单的爬虫
前言
最近telnet
命令用的比较多,所以记录一下。
一、场景
ping
应该是大家最常用的命令,可以测试节点之间通不通。但是我们如果想测试节点之间的指定端口通不通呢?
而且最近遇到了一些场景,就是配置端口映射的ip
,是不能ping
通的。
但是可以用ssh
指定端口连接。所以可以用telnet
连接。
二、介绍
1.测试端口
telnet ip port
2.访问百度
其实通过这个例子可以更好的理解http
协议。 依稀记得当年看《计算机网络:自顶向下方法》的时光。其实课本上描述的很详细了,什么定义GET
,Host
字段,然后实操呢?实操仅仅是考试吗?会影响我访问网页吗?
但其实一切都是可以实操的。计算机没有黑魔法,我们可以通过知识去理解这个真实的世界。
ping
获取百度地址
➜ ping www.baidu.com
PING www.a.shifen.com (180.101.50.188) 56(84) bytes of data.
64 bytes from 180.101.50.188 (180.101.50.188): icmp_seq=1 ttl=51 time=14.7 ms
64 bytes from 180.101.50.188 (180.101.50.188): icmp_seq=2 ttl=51 time=12.0 ms
^C64 bytes from 180.101.50.188: icmp_seq=3 ttl=51 time=11.1 ms
--- www.a.shifen.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2175ms
rtt min/avg/max/mdev = 11.125/12.580/14.652/1.504 ms
telnet
发送http
请求
➜ telnet 180.101.50.188 80
Trying 180.101.50.188...
Connected to 180.101.50.188.
Escape character is '^]'.
GET / HTTP/1.1
Connection: close
Host: www.baidu.com
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Content-Length: 9508
Content-Type: text/html
Date: Fri, 02 Feb 2024 05:43:38 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Pragma: no-cache
Server: BWS/1.1
Set-Cookie: BAIDUID=CB255C6E0972913C1C5DD40F2FA3A92C:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=CB255C6E0972913C1C5DD40F2FA3A92C; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1706852618; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BAIDUID=CB255C6E0972913C9B77469AFEF54677:FG=1; max-age=31536000; expires=Sat, 01-Feb-25 05:43:38 GMT; domain=.baidu.com; path=/; version=1; comment=bd
Traceid: 1706852618059642266612178835182056953725
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1
X-Xss-Protection: 1;mode=block
Connection: close
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta content="always" name="referrer"><meta name="description" content="全球领先的中文搜索引擎、致力于让网民更便捷地获取信息,找到所求。百度超过千亿的中文网页数据库,可以瞬间找到相关的搜索结果。"><link rel="shortcut icon" href="//www.baidu.com/favicon.ico" type="image/x-icon"><link rel="search" type="application/opensearchdescription+xml" href="//www.baidu.com/content-search.xml" title="百度搜索"><title>百度一下,你就知道</title>
一切没有黑魔法,都是约定好的文本。课本里的知识在真实世界里得到了映射。
3. 简单的爬虫
既然telnet
可以访问百度,那么telnet
是怎么访问百度的?好像只是一些简单的读写操作?所以我们能不能用linux
最基础的系统调用(syscall
)实现访问网页?这是不是爬虫的第一步呢?
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <iostream>
int main() {
std::string domain("www.baidu.com");
hostent* host = gethostbyname(domain.c_str());
std::string hname(host->h_name);
std::cout << hname << std::endl;
for (int i = 0; host->h_addr_list[i]; ++i) {
struct in_addr* addr = (struct in_addr*) host->h_addr_list[i];
std::string ip(inet_ntoa(*addr));
std::cout << ip << std::endl;
}
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1) {
std::cout << "Socket create failed" << std::endl;
return -1;
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = *(in_addr_t *)host->h_addr_list[0];
server_addr.sin_port = htons(80);
int err = connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (err < 0 ) {
std::cout << "error " << err << std::endl;
return -1;
}
std::string httptext;
httptext.append("GET / HTTP/1.1\r\n")
.append("Connection: close\r\n")
.append("Host: www.baidu.com\r\n").append("\r\n");
ssize_t ret = write(client_socket, httptext.c_str(), httptext.size());
if (ret != httptext.size()) {
std::cout << "error: ret != httptext.size()" << std::endl;
return -1;
} else {
std::cout << "success write" << std::endl;
}
char buffer[1024] = {0};
ssize_t bytes_received;
while(bytes_received = read(client_socket, buffer, sizeof(buffer))) {
std::cout << buffer << std::endl;
}
return 0;
}
编译,执行~