关于tcp客户端

关于tcp客户端

请求代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# -*- coding: UTF-8 -*-

'''
发送一个TCP请求总是需要
1. 建立client
2. 建立链接
3. 发送数据
4. 接收数据
'''

import socket

target_host = 'www.baidu.com'
target_port = '80'

# 建立一个socket对象
# AF_INET参数说明我们将使用标准的IPv4或者主机名
# SOCK_STREAM说明这将是一个TCP客户端
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接客户端
client.connect((target_host, target_port))

# 发送一些数据
client.send('GET / HTTP/1.1\r\nHost:baidu.com\r\n\r\n')

# 接受一些数据
response = client.recv(4096)

print(response)

响应代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Connection: Keep-Alive
Content-Length: 14615
Content-Type: text/html
Date: Thu, 28 Jun 2018 07:58:23 GMT
Last-Modified: Mon, 11 Jun 2018 11:19:00 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Pragma: no-cache
Server: BWS/1.1
Set-Cookie: BAIDUID=8D8D1B1785F34A55393458806C4E7D3B:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=8D8D1B1785F34A55393458806C4E7D3B; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1530172703; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1

<!DOCTYPE html><!--STATUS OK-->
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<link rel="dns-prefetch" href="//s1.bdstatic.com"/>
<link rel="dns-prefetch" href="//t1.baidu.com"/>
<link rel="dns-prefetch" href="//t2.baidu.com"/>
<link rel="dns-prefetch" href="//t3.baidu.com"/>
<link rel="dns-prefetch" href="//t10.baidu.com"/>
<link rel="dns-prefetch" href="//t11.baidu.com"/>
<link rel="dns-prefetch" href="//t12.baidu.com"/>
<link rel="dns-prefetch" href="//b1.bdstatic.com"/>
<title>百度一下,你就知道</title>
<link href="http://s1.bdstatic.com/r/www/cache/static/home/css/in

bug说明

1
SyntaxError: Non-ASCII character '\xe5' in file kNN.py on line 24, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

出现问题的原因:
Python默认是以ASCII作为编码方式的,如果在自己的Python源码中包含了中文(或者其他非英语系的语言),此时即使你把自己编写的Python源文件以UTF-8格式保存了,但实际上,这依然是不行的。
解决办法很简单,只要在文件开头加入下面代码就行了

1
# -*- coding: UTF-8 -*-

解释

关于请求的解释
1
2
GET / HTTP/1.1
Host: www.baidu.com
  • 首先有一个动词,我们叫HTTP Method,常见的有GET,POST,PUT,DELETE,OPTIONS,HEAD,不常见的有TRACE,CONNECT。
  • 然后一个空格,后面接了一个/,表示我们请求这个站点的根目录,或者根网页。
  • 再之后是HTTP/1.1,这是HTTP协议的版本号, 根据RFC说明,HTTP协议的版本号要支持多位数字的比较,而不能直接用ASCII比较,例如HTTP/11.22要比HTTP/2.1更大, 且版本号是HTTP/.的方式,major是大版本,minor是小版本,例如:HTTP/0.9,HTTP/1.1,HTTP/2.0。
  • 然后是换行符。
  • 在此之后,是Host: www.baidu.com,这叫virtual host,是HTTP协议为了支持同一个IP上服务多个网站而来的,服务器通过判断 这个字段里的内容来将一个请求打到不同的内容服务器上。
  • 在之后是两个换行符。

    请注意,HTTP协议中的换行,是\r\n,所以上面这个请求,把换行符和空格打出来,实际上是这样的:

1
GET<space>/<space>HTTP/1.1\r\nHost:<space>www.baidu.com\r\n\r\n
  • 两个\r\n表示HTTP协议内容头部的结束,正文的开始,当然也可以不接正文。正文也是各种各样的字符串,那么问题来了,服务器怎么知道 客户端请求里带的是什么内容呢?所以有一个头部叫做Content-Type,他就是用来表明此次携带的内容类型是什么,例如:
    1
    2
    3
    GET / HTTP/1.1
    Host: www.baidu.com
    Content-Type: text/html

Author: Vallzey
Link: https://vallzey.github.io/2018/07/04/关于tcp客户端/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.