python网络编程难点_python之路网络编程总结(三)
2018-9-22 20:58:25
1. 端口
1.1知名端口是眾所周知的端口,范圍從0-1023
例: 80端口分配給HTTP服務(wù)
21 端口分配給FTP服務(wù)
1.2動(dòng)態(tài)端口 : 范圍從1024 - 65535
2. 什么是socket?
socket(簡(jiǎn)稱 套接字) 是進(jìn)程間通信的一種方式,它與其他進(jìn)程間通信的一個(gè)主要不同的是:
它能實(shí)現(xiàn)不同主機(jī)間的進(jìn)程間通信,我們網(wǎng)絡(luò)上各種各樣的服務(wù)器大多都是基于Socket來完成
通訊的
#創(chuàng)建一個(gè)tcp socket (tcp套接字)
importsocket
socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)print("Socket Created")
創(chuàng)建一個(gè)udp socket(udp套接字)importsocket
socket=socket.socket(socket.AF_INET, socket.SOCKET_DGRAM)print("Socket Created")
3. 一個(gè)多線程QQ聊天Demo
from threading importThreadfrom socket import *
#1.接收數(shù)據(jù),然后打印
defrecvDate():whileTrue:
recvInfo= udpSocket.recvfrom(1024)print(">>%s:%s"%(str(recvInfo[1]),recvInfo[0]))#2.檢測(cè)鍵盤,發(fā)送數(shù)據(jù)
defsendDate():whileTrue:
sendInfo= input("<<")
udpsocket.sendto(sendInfo.endcode("gb2312"),(destIp,destPort))
udpSocket=None #存儲(chǔ)對(duì)象時(shí)默認(rèn)為None
destIp = ""destPort=0defmain():globaludpSocketglobaldestIpglobaldestPost#創(chuàng)建udp套接字
destIp = input("對(duì)方的IP:")
destPort= input(("對(duì)方的接口"))
udpSocket=socket(AF_INET,SOCK_DGRAM)
udpSocket.bind(("",4567))#創(chuàng)建兩個(gè)線程
tr = Thread(target=recvDate())
ts= Thread(target=sendDate())
tr.start()
ts.start()
tr.join()
ts.join()if __name__ == "__main__":
main()
4.socket 的客戶端與服務(wù)端
#服務(wù)端端:
from socket import *
#tcp參數(shù)是SOCK_STREAM
socket =socket.socket(AF_INET, SOCK_STREAM)#綁定IP和端口
socket.bind("127.0.0.1",8080)#監(jiān)聽端口
socket.listen(5)#返回是一個(gè)元組, 接受 新的客戶端, addr 表示 新的客戶端的IP和port
conn, addr =socket.accept()
recv= conn.recv(1024)#像IO操作一樣,執(zhí)行完畢后關(guān)閉:
conn.close()
socket.close()#tcp 客戶端
from socket import *
#創(chuàng)建一個(gè)套接字
socket =socket(AF_INET,SOCK_STREAM)
socket.connect(("127.0.0.1",8000))#發(fā)送消息#注意:#1.tcp客戶端已經(jīng)連接好了服務(wù)器,所以在喲戶的數(shù)據(jù)發(fā)送中,不需要填寫對(duì)方的ip和port-->打電話#2.udp在發(fā)送數(shù)據(jù)的時(shí)候,因?yàn)闆]有之前的連接,所依需要,在每次的發(fā)送中,都要填寫接受方的ip和port---->寫信
socket.send("haha".encode("gb2312"))#接收消息
recv = socket.recv(1024)
socket.close()
5.TCP部分內(nèi)容
TCP的三次握手!!!!!!!
關(guān)于TCP的三次握手 參考連接:https://0x9.me/JB3NX https://0x9.me/L5XlQ
OSI模型:就是七層物理層
ICMP: 我ping你的時(shí)候要用,不僅要知道ip地址和網(wǎng)卡號(hào)mac地址
ARP : 在我和你通訊前不知道的mac地址需要廣播一下,當(dāng)我說的是你的時(shí)候就回消息!獲取mac地址(根據(jù)ip找mac)
rarp :根據(jù)mac地址找IP
路由器:能夠鏈接不同的網(wǎng)絡(luò)使他們之間能夠通信
mac:就是手拉手傳輸數(shù)據(jù)用的
DNS : 解析域名
DHCP:一種協(xié)議,自動(dòng)分配ip 發(fā)現(xiàn)局域網(wǎng)中沒有ip的電腦分配ip
短連接:數(shù)據(jù)少,直接發(fā)送
長(zhǎng)連接:持續(xù)發(fā)送據(jù),視頻網(wǎng)站
6. 面試題: 訪問百度的整個(gè)過程
打開瀏覽器,訪問百度的過程:
1.我的電腦確定有無網(wǎng)關(guān),arp得到默認(rèn)網(wǎng)管mac地址, 如果用IP訪問 三次握手,客戶端發(fā)送請(qǐng)求數(shù)據(jù),對(duì)方返回?cái)?shù)據(jù)
2. 域名訪問:
1.先要解析出baidu.com對(duì)應(yīng)的ip地址
1.1先知道默認(rèn)網(wǎng)關(guān)的mac
1.1.1使用arp獲取默認(rèn)網(wǎng)管的mac地址
2.組織數(shù)據(jù) 發(fā)送給默認(rèn)網(wǎng)關(guān)(ip還是dns的ip,但是mac地址是默認(rèn)網(wǎng)關(guān)的地址)
3.默認(rèn)網(wǎng)關(guān)擁有轉(zhuǎn)發(fā)數(shù)據(jù)的能力,把數(shù)據(jù)轉(zhuǎn)發(fā)給路由器
4.路由器根據(jù)自己的路由協(xié)議,來選擇一個(gè)適合的較快路徑轉(zhuǎn)發(fā)數(shù)據(jù)給目的網(wǎng)關(guān)
5.目的網(wǎng)關(guān)(dns服務(wù)器所在的網(wǎng)關(guān)),把數(shù)據(jù)轉(zhuǎn)發(fā)給dns服務(wù)器
6.dns服務(wù)器查詢解析出baidu.com對(duì)應(yīng)的ip地址,并發(fā)它原路返回,請(qǐng)求這個(gè)域名的client
2.得到了baidu.com對(duì)應(yīng)的IP地址之后,會(huì)發(fā)送tcp的3次握手,進(jìn)行連接
3.使用http協(xié)議發(fā)送請(qǐng)求數(shù)據(jù)給web服務(wù)器
4.web服務(wù)器收到數(shù)據(jù)請(qǐng)求后,通過查詢自己的服務(wù)器得到相應(yīng)的結(jié)果,原路返回給瀏覽器
5.瀏覽器接收到數(shù)據(jù)后,通過瀏覽器自己的渲染功能來顯示這個(gè)網(wǎng)頁(yè)
6.瀏覽器關(guān)閉 tcp連接,即4次揮手
完成整個(gè)訪問過程
7. Web服務(wù)器內(nèi)容: web服務(wù)器的原理!!就是 sockeSever! 其實(shí)為了后面學(xué)Django好理解!
.
#服務(wù)端
'''創(chuàng)建一個(gè)靜態(tài)服務(wù)器訪問指定頁(yè)面
http://127.0.0.1:8000/'''
importsocketfrom multiprocessing importProcess
HTML_ROOT_DIR= ""
defhandle_client(client_socket):'''處理客戶端請(qǐng)求'''
#獲取客戶端請(qǐng)求數(shù)據(jù)
request_data = client_socket.recv(1024)print("request_data:",request_data)#構(gòu)造相應(yīng)數(shù)據(jù)
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_bodyprint("response data:",response)#向客戶端返回響應(yīng)數(shù)據(jù)
client_socket.send(bytes(reponse,"utf-8"))#關(guān)閉客戶端連接
client_socket.close()defmain():#tcp socket 服務(wù)端
server_socket =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_socket.bind(("",8003))
server_socket.listen(128)whileTrue:
client_socket,client_address=server_socket.accept()print("")#創(chuàng)建一個(gè)進(jìn)程
handle_client_process = Process(target=handle_client,args=(client_socket,))
handle_client_process.start()
client_socket.close()if __name__ == '__main__':
main()
#客戶端!
'''創(chuàng)建一個(gè)靜態(tài)服務(wù)器訪問指定頁(yè)面
http://127.0.0.1:8000/index.html'''
importsocketimportrefrom multiprocessing importProcess#設(shè)置靜態(tài)文件根目錄 常量全大寫
HTML_ROOT_DIR = "./html"
defhandle_client(client_socket):'''處理客戶端請(qǐng)求'''
#獲取客戶端請(qǐng)求數(shù)據(jù)
request_data = client_socket.recv(1024)print("request_data:",request_data)
request_lines=request_data.splitines()for line inrequest_lines:print(line)#解析請(qǐng)求報(bào)文
#'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)#判斷反過來寫,防止少寫一個(gè)等號(hào) 不可變的寫在左邊
if "/" ==file_name:
file_name="/index.html"
#打開文件,讀取內(nèi)容
try:
file= open(HTML_ROOT_DIR+file_name,"rb")exceptIOError:
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()#構(gòu)造相應(yīng)數(shù)據(jù)
response_start_line = "HTTP/1.1 200 OK\r\n"response_headers= "Sever:My server\r\n"response_body=file_datafinally:
response= response_start_line+response_headers+"\r\n"+response_bodyprint("response data:",response)#向客戶端返回響應(yīng)數(shù)據(jù) python3需要轉(zhuǎn)換成字節(jié)
client_socket.send(bytes(reponse,"utf-8"))#關(guān)閉客戶端連接
client_socket.close()defmain():#tcp socket 服務(wù)端
server_socket =socket.socket(socket.AF_INET,socket.SOCK_STREAM)#設(shè)置socket參數(shù)
server_socket.setsockopt(socket.SOL_SOCKET,socket.SOL_REUSEADDR,1)
server_socket.bind(("",8000))
server_socket.listen(128)whileTrue:
client_socket,client_address=server_socket.accept()print("")#創(chuàng)建一個(gè)進(jìn)程
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網(wǎng)絡(luò)編程最主要的 就是socket 下面開始進(jìn)行 多線程部分!
# 其他的 網(wǎng)絡(luò)編程后續(xù)再補(bǔ)充!
總結(jié)
以上是生活随笔為你收集整理的python网络编程难点_python之路网络编程总结(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux命令行挂载NTFS文件系统的移
- 下一篇: 【Python教程】雨痕 的《Pytho