python學習筆記-網路程式設計
#=========================網路程式設計=====================
# 網路:
# 網路協議: 一套規則
# 網路模型:
# 七層模型,ISO
# 四層模型,TCP/IP
# 每一層都有相應的協議負責交換資訊或者協同工作
# TCP/IP 協議族
# IP地址:負責在網路上唯一定位一個機器
# 埠
# 範圍: 0#65535
# 知名埠:0#1023
# 非知名埠:1024#
# TCP/UDP協議
# UDP:非安全的不面向連結的傳輸
# 安全性差
# 大小限制64kb
# 沒有順序
# 速度快
# TCP
# 基於連結的通訊
#=========================SOCKET程式設計-UDP=========================
# socket(套接字): 是一個網路通訊的端點, 能實現不同主機的程序通訊,網路大多基於Socket通訊
# 通過IP+埠定位對方併發送訊息的通訊機制
# 分為UDP和TCP
# 客戶端Client: 發起訪問的一方
# 伺服器端Server:接受訪問的一方
# UDP 程式設計
# Server端流程
1. 建立socket,socket是負責具體通訊的一個例項
2. 繫結,為建立的socket指派固定的埠和ip地址
3. 接受對方傳送內容
4. 給對方傳送反饋,此步驟為非必須步驟
# Client端流程
1. 建立通訊的socket
2. 傳送內容到指定伺服器
3. 接受伺服器給定的反饋內容
# 伺服器案例:
'''
Server端流程
1. 建立socket,socket是負責具體通訊的一個例項
2. 繫結,為建立的socket指派固定的埠和ip地址
3. 接受對方傳送內容
4. 給對方傳送反饋,此步驟為非必須步驟
'''
# socket模組負責socket程式設計
import socket
def serverFunc():
# 1. 建立socket
# socket.AF_INET:使用ipv4協議族
# socket.SOCK_DGRAM: 使用UDP通訊
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2. 繫結ip和port
# 127.0.0.1: 這個ip地址代表的是機器本身
# 7852: 隨手指定的埠號
# 地址是一個tuple型別,(ip, port)
addr = ("127.0.0.1", 7852 )
sock.bind( addr )
# 接受對方訊息
# 等待方式為死等, 沒有其他可能性
# recvfrom接受的返回值是一個tuple,前一項表示資料,後一項表示地址
# 引數的含義是緩衝區大小
# rst = sock.recvfrom(500)
data, addr = sock.recvfrom(500)
# 傳送過來的資料是bytes格式,必須通過解碼才能得到str格式內容
# decode預設引數是utf8
text = data.decode()
print(text)
# 給對方返回的訊息
rsp = "return massage:get it"
# 傳送的資料需要編碼成bytes格式
# 預設是utf8
data = rsp.encode()
sock.sendto(data, addr)
if __name__ == '__main__':
# 伺服器程式要求永久執行,一般用死迴圈處理
while 1:
try:
serverFunc()
except Exception as e:
print(e)
time.sleep(1)
# 客戶端案例:
import socket
'''
- Client端流程
1. 建立通訊的socket
2. 傳送內容到指定伺服器
3. 接受伺服器給定的反饋內容
'''
def clientFunc():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
text = "go go !"
# 傳送的資料必須是bytes格式
data = text.encode()
# 傳送
sock.sendto(data, ("127.0.0.1", 7852))
data, addr = sock.recvfrom(200)
data = data.decode()
print(data)
if __name__ == '__main__':
clientFunc()
#=========================SOCKET程式設計-TCP=========================
# 面向連結的傳輸,即每次傳輸之前需要先建立一個連結
# 客戶端和伺服器端兩個程式需要編寫
# Server端的編寫流程
1. 建立socket負責具體通訊,這個socket其實只負責接受對方的請求,真正通訊的是連結後從新建立的socket
2. 繫結埠和地址
3. 監聽接入的訪問socket
4. 接受訪問的socket,可以理解接受訪問即建立了一個通訊的連結通路
5. 接受對方的傳送內容,利用接收到的socket接收內容
6. 如果有必要,給對方傳送反饋資訊
7. 關閉連結通路
# Client端流程
1. 建立通訊socket
2. 連結對方,請求跟對方建立通路
3. 傳送內容到對方伺服器
4. 接受對方的反饋
5. 關閉連結通路
# TCP服務端案例:
import socket
def tcp_srv():
# 1. 建立socket負責具體通訊,這個socket其實只負責接受對方的請求,真正通訊的是連結後從新建立的socket
# 需要用到兩個引數
# AF_INET: 含義同udp一致
# SOCK_STREAM: 表明是使用的tcp進行通訊
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 繫結埠和地址
# 此地址資訊是一個元祖型別內容,元祖分兩部分,第一部分為字串,代表ip,第二部分為埠,是一個整數,推薦大於10000
addr = ("127.0.0.1", 8998)
sock.bind(addr)
# 3. 監聽接入的訪問socket
sock.listen()
while True:
# 4. 接受訪問的socket,可以理解接受訪問即建立了一個通訊的連結通路
# accept返回的元祖第一個元素賦值給skt,第二個賦值給addr
skt,addr = sock.accept()
# 5. 接受對方的傳送內容,利用接收到的socket接收內容
# 500代表接收使用的buffersize
#msg = skt.receive(500)
msg = skt.recv(500)
# 接受到的是bytes格式內容
# 想得到str格式的,需要進行解碼
msg = msg.decode()
rst = "Received msg: {0} from {1}".format(msg, addr)
print(rst)
# 6. 如果有必要,給對方傳送反饋資訊
skt.send(rst.encode())
# 7. 關閉連結通路
skt.close()
if __name__ == "__main__":
print("Starting tcp server.......")
tcp_srv()
print("Ending tcp server.......")
# TCP客戶端案例:
import socket
def tcp_clt():
# 1. 建立通訊socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 連結對方,請求跟對方建立通路
addr = ("127.0.0.1", 8998)
sock.connect(addr)
# 3. 傳送內容到對方伺服器
msg = "I love wangxiaojing"
sock.send(msg.encode())
# 4. 接受對方的反饋
rst = sock.recv(500)
print(rst.decode())
# 5. 關閉連結通路
sock.close()
if __name__ == "__main__":
tcp_clt()
#=========================FTP程式設計=========================
# FTP(FileTransferProtocal)檔案傳輸協議
# 用途: 定製一些特殊的上傳下載檔案的服務
# 使用者分類: 登陸FTP伺服器必須有一個賬號
# Real賬戶: 註冊賬戶
# Guest賬戶: 可能臨時對某一類人的行為進行授權
# Anonymous賬戶: 匿名賬戶,允許任何人
# FTP工作流程
1. 客戶端連結遠端主機上的FTP伺服器
2. 客戶端輸入使用者名稱和密碼(或者“anonymous”和電子郵件地址)
3. 客戶端和伺服器進行各種檔案傳輸和資訊查詢操作
4. 客戶端從遠端FTP伺服器退出,結束傳輸
# FTP檔案表示
# 分三段表示FTP伺服器上的檔案
# HOST: 主機地址,類似於 ftp.mozilla.org, 以ftp開頭
# DIR:目錄, 表示檔案所在本地的路徑,例如 pub/android/focus/1.1#RC1/
# File: 檔名稱, 例如 Klar#1.1#RC1.apk
# 如果想完整精確表示ftp上某一個檔案,需要上述三部分組合在一起
# FTP案例:
# 需要匯入相應包,主要是ftplib
import ftplib # 關於FTP的操作都在這個包裡邊
import os
import socket
# 三部分精確表示在ftp伺服器上的某一個檔案
# 好多公開ftp伺服器訪問會出錯或者沒有反應
HOST = "ftp.acc.umu.se"
DIR = 'Public/EFLIB/'
FILE = 'README'
# 1. 客戶端連結遠端主機上的FTP伺服器
try:
f = ftplib.FTP()
# 通過設定除錯級別可以方便除錯
f.set_debuglevel(2)
# 連結主機地址
f.connect(HOST)
except Exception as e:
print(e)
exit()
print("***Connected to host {0}".format(HOST))
# 2. 客戶端輸入使用者名稱和密碼(或者“anonymous”和電子郵件地址)
try:
# 登入如果沒有輸入使用者資訊,則預設使用匿名登入
f.login()
except Exception as e:
print(e)
exit()
print("***Logged in as 'anonymous'")
# 3. 客戶端和伺服器進行各種檔案傳輸和資訊查詢操作
try:
# 更改當前目錄到指定目錄
f.cwd(DIR)
except Exception as e:
print(e)
exit()
print("*** Changed dir to {0}".format(DIR))
try:
# 從FTP伺服器上下載檔案
# 第一個引數是ftp命令
# 第二個引數是回撥函式
# 此函式的意思是,執行RETR命令,下載檔案到本地後,執行回撥函式
f.retrbinary('RETR {0}'.format(FILE), open(FILE, 'wb').write)
except Exception as e:
print(e)
exit()
# 4. 客戶端從遠端FTP伺服器退出,結束傳輸
f.quit()
#=========================Mail程式設計=========================
## 電子郵件的歷史
# 起源
# 1969 Leonard K. 教授發給同時的 “LO”
# 1971 美國國防部自主的阿帕網(Arpanet)的通訊機制
# 通訊地址裡用"@"
# 1987年中國的第一份電子郵件
# "Across the Great Wall we can reach every corner in the world"
# 管理程式
# Euroda使郵件普及
# Netscape,outlook,forxmail後來居上
# Hotmal使用瀏覽器傳送郵件i
# 參考資料
# [官網](https://docs.python.org/3/library/email.mime.html)
## 郵件工作流程
# MUA(MailUserAgent)郵件使用者代理
# MTA(MailTransferAgent)郵件傳輸代理
# MDA(MailDeliveryAgent)郵件投遞代理
# [email protected], 老師,北京海淀
# [email protected], 學生,上海江岸區
# 流程
1. MUA#>MTA, 郵件已經在伺服器上了
2. qq MTA#>.........#>sina MTA, 郵件在新浪的伺服器上
3. sina MTA#> sina MDA, 此時郵件已經在你的郵箱裡了
4. sina MDA #> MUA(Foxmail/Outlook), 郵件下載到本地電腦
# 編寫程式
# 傳送: MUA#>MTA with SMTP:SimpleMailTransferProtocal,包含MTA#>MTA
# 接受: MDA#>MUA with POP3 and IMAP:PostOfficeProtocal v3 and InternetMessageAccessProtocal v4
# 準備工作
# 註冊郵箱(以qq郵箱為例)
# 第三方郵箱需要特殊設定, 以qq郵箱為例
# 進入設定中心
# 取得授權碼
# Python for mail
# SMTP協議負責傳送郵件
# 使用smtplib模組傳送郵件
# 1、使用email模組構建郵件
# 純文字郵件
# 案例:
# 匯入相應的包
import smtplib
from email.mime.text import MIMEText
# MIMEText三個主要引數
# 1. 郵件內容
# 2. MIME子型別,在此案例我們用plain表示text型別
# 3. 郵件編碼格式
msg = MIMEText("Hello, i am beijing tulingxueyuan ", "plain", "utf-8")
# 發件人的email地址
from_addr = "[email protected]"
# 此處密碼是經過申請設定後的授權碼,不是不是不是你的qq郵箱密碼
from_pwd = "hjpovygcxmrshhcj"
# 收件人資訊
to_addr = "[email protected]"
# 輸入SMTP伺服器地址
# 騰訊qq郵箱所的smtp地址是 smtp.qq.com
smtp_srv = "smtp.qq.com"
try:
# 加密傳輸
# 第一個是伺服器地址,但一定是bytes格式,所以需要編碼
# 第二個引數是伺服器的接受訪問埠
# srv = smtplib.SMTP_SSL(smtp_srv.encode(), 465) #SMTP協議預設埠25
# qq郵箱要求使用 TLS加密傳輸
server = smtplib.SMTP(smtp_srv.encode(), 25) # SMTP協議預設埠是25
server.starttls()
# 設定除錯級別
# 通過設定除錯等級,可以清楚的看到傳送郵件的互動步驟
server.set_debuglevel(1)
#登入郵箱傳送
srv.login(from_addr, from_pwd)
# 傳送郵件
# 三個引數
# 1. 傳送地址
# 2. 接受地址,必須是list形式
# 3. 傳送內容,作為字串傳送
srv.sendmail(from_addr, [to_addr], msg.as_string())
srv.quit()
except Exception as e:
print(e)
# HTML格式郵件傳送
# 準備HTML程式碼作為內容
# 把郵件的subtpye設為html
# 傳送
# 案例片段,其他與TEXT傳送一樣:
mail_content = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1> 這是一封HTML格式郵件</h1>
</body>
</html>