python之路网络编程总结(三)
2018-9-22 20:58:25
1. 端口
1.1知名端口是众所周知的端口,范围从0-1023
例: 80端口分配给HTTP服务
21 端口分配给FTP服务
1.2 动态端口 : 范围从1024 - 65535
2. 什么是socket?
socket(简称 套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同的是:
它能实现不同主机间的进程间通信,我们网络上各种各样的服务器大多都是基于Socket来完成
通讯的
# 创建一个tcp socket (tcp套接字) import socket socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print("Socket Created") 创建一个udp socket(udp套接字) import socket socket = socket.socket(socket.AF_INET, socket.SOCKET_DGRAM) print("Socket Created")
3. 一个多线程QQ聊天Demo
from threading import Thread from socket import * #1.接收数据,然后打印 def recvDate(): while True: recvInfo = udpSocket.recvfrom(1024) print(">>%s:%s"%(str(recvInfo[1]),recvInfo[0])) #2.检测键盘,发送数据 def sendDate(): while True: sendInfo = input("<<") udpsocket.sendto(sendInfo.endcode("gb2312"),(destIp,destPort)) udpSocket =None #存储对象时默认为None destIp = "" destPort = 0 def main(): global udpSocket global destIp global destPost # 创建udp套接字 destIp = input("对方的IP:") destPort = input(("对方的接口")) udpSocket = socket(AF_INET,SOCK_DGRAM) udpSocket.bind(("",4567)) #创建两个线程 tr = Thread(target=recvDate()) ts = Thread(target=sendDate()) tr.start() ts.start() tr.join() ts.join() if __name__ == "__main__": main()
4.socket 的客户端与服务端
# 服务端端: from socket import * # tcp参数是SOCK_STREAM socket = socket.socket(AF_INET, SOCK_STREAM) # 绑定IP和端口 socket.bind("127.0.0.1",8080) # 监听端口 socket.listen(5) # 返回是一个元组, 接受 新的客户端, addr 表示 新的客户端的IP和port conn, addr = socket.accept() recv = conn.recv(1024) # 像IO操作一样,执行完毕后关闭: conn.close() socket.close() #tcp 客户端 from socket import * #创建一个套接字 socket = socket(AF_INET,SOCK_STREAM) socket.connect(("127.0.0.1",8000)) #发送消息 #注意: #1.tcp客户端已经连接好了服务器,所以在哟户的数据发送中,不需要填写对方的ip和port-->打电话 #2.udp在发送数据的时候,因为没有之前的连接,所依需要,在每次的发送中,都要填写接受方的ip和port---->写信 socket.send("haha".encode("gb2312")) #接收消息 recv = socket.recv(1024) socket.close()
5.TCP部分内容
TCP的三次握手!!!!!!!
关于TCP的三次握手 参考连接:https://0x9.me/JB3NX https://0x9.me/L5XlQ
OSI模型:就是七层物理层
ICMP: 我ping你的时候要用,不仅要知道ip地址和网卡号mac地址
ARP : 在我和你通讯前不知道的mac地址需要广播一下,当我说的是你的时候就回消息!获取mac地址(根据ip找mac)
rarp :根据mac地址找IP
路由器:能够链接不同的网络使他们之间能够通信
mac:就是手拉手传输数据用的
DNS : 解析域名
DHCP:一种协议,自动分配ip 发现局域网中没有ip的电脑分配ip
短连接:数据少,直接发送
长连接:持续发送据,视频网站
6. 面试题: 访问百度的整个过程
打开浏览器,访问百度的过程:
1.我的电脑确定有无网关,arp得到默认网管mac地址, 如果用IP访问 三次握手,客户端发送请求数据,对方返回数据
2. 域名访问:
1.先要解析出baidu.com对应的ip地址
1.1先知道默认网关的mac
1.1.1使用arp获取默认网管的mac地址
2.组织数据 发送给默认网关(ip还是dns的ip,但是mac地址是默认网关的地址)
3.默认网关拥有转发数据的能力,把数据转发给路由器
4.路由器根据自己的路由协议,来选择一个适合的较快路径转发数据给目的网关
5.目的网关(dns服务器所在的网关),把数据转发给dns服务器
6.dns服务器查询解析出baidu.com对应的ip地址,并发它原路返回,请求这个域名的client
2.得到了baidu.com对应的IP地址之后,会发送tcp的3次握手,进行连接
3.使用http协议发送请求数据给web服务器
4.web服务器收到数据请求后,通过查询自己的服务器得到相应的结果,原路返回给浏览器
5.浏览器接收到数据后,通过浏览器自己的渲染功能来显示这个网页
6.浏览器关闭 tcp连接,即4次挥手
完成整个访问过程
7. Web服务器内容: web服务器的原理!!就是 sockeSever! 其实为了后面学Django好理解!
.
# 服务端 ''' 创建一个静态服务器访问指定页面 http://127.0.0.1:8000/ ''' import socket from multiprocessing import Process HTML_ROOT_DIR = "" def handle_client(client_socket): ''' 处理客户端请求''' # 获取客户端请求数据 request_data = client_socket.recv(1024) print("request_data:",request_data) # 构造相应数据 response_start_line = "HTTP/1.1 200 OK\r\n" response_headers = "Sever:My server\r\n" response_body = "hello itcast" response = response_start_line+response_headers+"\r\n"+response_body print("response data:",response) # 向客户端返回响应数据 client_socket.send(bytes(reponse,"utf-8")) # 关闭客户端连接 client_socket.close() def main(): #tcp socket 服务端 server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_socket.bind(("",8003)) server_socket.listen(128) while True: client_socket,client_address = server_socket.accept() print("") #创建一个进程 handle_client_process = Process(target=handle_client,args=(client_socket,)) handle_client_process.start() client_socket.close() if __name__ == '__main__': main()
# 客户端! ''' 创建一个静态服务器访问指定页面 http://127.0.0.1:8000/index.html ''' import socket import re from multiprocessing import Process # 设置静态文件根目录 常量全大写 HTML_ROOT_DIR = "./html" def handle_client(client_socket): ''' 处理客户端请求''' # 获取客户端请求数据 request_data = client_socket.recv(1024) print("request_data:",request_data) request_lines = request_data.splitines() for line in request_lines: print(line) #解析请求报文 # 'GET?HTTP/1.1' request_start_line = request_lines[0] # 使用正则,拿到 index.html file_name = re.match(r"\w+ +(/[^ ]*) ",request_start_line.decode(utf-8)).group(1) # 判断反过来写,防止少写一个等号 不可变的写在左边 if "/" == file_name: file_name ="/index.html" # 打开文件,读取内容 try: file = open(HTML_ROOT_DIR+file_name,"rb") except IOError: response_start_line ="HTTP/1.1 404 NOt Found\r\n" response_headers = "server: My Sever\r\n" response_body = "The file is not found!" else: file_data = file.read().decode("utf-8") file.close() # 构造相应数据 response_start_line = "HTTP/1.1 200 OK\r\n" response_headers = "Sever:My server\r\n" response_body = file_data finally: response = response_start_line+response_headers+"\r\n"+response_body print("response data:",response) # 向客户端返回响应数据 python3需要转换成字节 client_socket.send(bytes(reponse,"utf-8")) # 关闭客户端连接 client_socket.close() def main(): #tcp socket 服务端 server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #设置socket参数 server_socket.setsockopt(socket.SOL_SOCKET,socket.SOL_REUSEADDR,1) server_socket.bind(("",8000)) server_socket.listen(128) while True: client_socket,client_address = server_socket.accept() print("") #创建一个进程 handle_client_process = Process(target=handle_client,args=(client_socket,)) handle_client_process.start() client_socket.close() if __name__ == '__main__': main()
# 2018-9-22 20:44:38
# python网络编程最主要的 就是socket 下面开始进行 多线程部分!
# 其他的 网络编程后续再补充!