17--Python 網(wǎng)絡(luò)編程和郵件

@Author : Roger TX (425144880@qq.com)
@Link : https://github.com/paotong999

一、計(jì)算機(jī)網(wǎng)絡(luò)協(xié)議

計(jì)算機(jī)網(wǎng)絡(luò)就是把各個(gè)計(jì)算機(jī)連接到一起,讓網(wǎng)絡(luò)中的計(jì)算機(jī)可以互相通信。網(wǎng)絡(luò)編程就是如何在程序中實(shí)現(xiàn)兩臺(tái)計(jì)算機(jī)的通信。而確切地說,網(wǎng)絡(luò)通信是兩臺(tái)計(jì)算機(jī)上的兩個(gè)進(jìn)程之間的通信。

1、OSI 參考模型和 TCP/IP 分層模型

  1. OSI 參考模型把計(jì)算機(jī)網(wǎng)絡(luò)分成物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會(huì)話層、表示層、應(yīng)用層七層,OSI 模式已成為各種計(jì)算機(jī)網(wǎng)絡(luò)結(jié)構(gòu)的參考標(biāo)準(zhǔn)。
  2. IP協(xié)議(Internet Protocol)又稱網(wǎng)際協(xié)議,是支持網(wǎng)間互聯(lián)的數(shù)據(jù)報(bào)協(xié)議。IP 協(xié)議提供了網(wǎng)間連接的完善功能,包括 IP 數(shù)據(jù)報(bào)規(guī)定的互聯(lián)網(wǎng)絡(luò)范圍內(nèi)的地址格式。
  3. TCP協(xié)議(Transmission Control Protocol)又稱傳輸控制協(xié)議,它規(guī)定了一種可靠的數(shù)據(jù)信息傳遞服務(wù)。

雖然 IP 和 TCP 這兩個(gè)協(xié)議的功能不盡相同,也可以分開單獨(dú)使用,但它們是在同一個(gè)時(shí)期作為一個(gè)協(xié)議來設(shè)計(jì)的,并且在功能上是互補(bǔ)的,因此在實(shí)際使用中常常把這兩個(gè)協(xié)議統(tǒng)稱為 TCP/IP 協(xié)議。

OSI 參考模型和 TCP/IP 分層模型的大致對(duì)應(yīng)關(guān)系

參考模型

2、TCP/IP協(xié)議和端口號(hào)

TCP/IP協(xié)議

  1. IP地址實(shí)際上是一個(gè)32位整數(shù)(稱為IPv4),以字符串表示的IP地址如192.168.0.1實(shí)際上是把32位整數(shù)按8位分組后的數(shù)字表示,目的是便于閱讀。
  2. IPv6地址實(shí)際上是一個(gè)128位整數(shù),它是目前使用的IPv4的升級(jí)版,以字符串表示類似于 2001:0db8:85a3:0042:1000:8a2e:0370:7334。
  3. TCP協(xié)議則是建立在IP協(xié)議之上的。TCP協(xié)議負(fù)責(zé)在兩臺(tái)計(jì)算機(jī)之間建立可靠連接,保證數(shù)據(jù)包按順序到達(dá)。TCP協(xié)議會(huì)通過握手建立連接,然后,對(duì)每個(gè)IP包編號(hào),確保對(duì)方按順序收到,如果包丟掉了,就自動(dòng)重發(fā)。
  4. 一個(gè)TCP報(bào)文除了包含要傳輸?shù)臄?shù)據(jù)外,還包含源IP地址和目標(biāo)IP地址,源端口和目標(biāo)端口。

端口號(hào)
不同的應(yīng)用程序處理不同端口上的數(shù)據(jù),在同一臺(tái)機(jī)器中不能有兩個(gè)程序使用同一個(gè)端口。
端口號(hào)可以為 0~65535,通常將端口分為如下三類:

  • 公認(rèn)端口(Well Known Port):端口號(hào)為 0~1023,它們緊密地綁定(Binding)一些特定的服務(wù)。
  • 注冊(cè)端口(Registered Port):端口號(hào)為 1024~49151,它們松散地綁定一些服務(wù)。應(yīng)用程序通常應(yīng)該使用這個(gè)范圍內(nèi)的端口。
  • 動(dòng)態(tài)和/或私有端口(Dynamic and/or Private Port):端口號(hào)為 49152~65535,這些端口是應(yīng)用程序使用的動(dòng)態(tài)端口,應(yīng)用程序一般不會(huì)主動(dòng)使用這些端口。

二、Python網(wǎng)絡(luò)編程模塊

四層網(wǎng)絡(luò)模型及對(duì)應(yīng)的協(xié)議
  • 網(wǎng)絡(luò)接口層和網(wǎng)絡(luò)層都是協(xié)議底層,通常來說,很少會(huì)直接基于底層進(jìn)行應(yīng)用程序編程。
  • 傳輸層協(xié)議主要是 TCP 和 UDP,Python 提供了 socket 等模塊針對(duì)傳輸層協(xié)議進(jìn)行編程。
  • 應(yīng)用層協(xié)議更豐富,F(xiàn)TP、HTTP、TELNET 等協(xié)議都屬于應(yīng)用層協(xié)議,Python 同樣為基于應(yīng)用層協(xié)議的編程提供了豐富的支持。

Python 標(biāo)準(zhǔn)庫中的網(wǎng)絡(luò)相關(guān)模塊

模塊 描述
socke 基于傳輸層 TCP、UDP 協(xié)議進(jìn)行網(wǎng)絡(luò)編程的模塊
asyncore socket 模塊的異步版,支持基于傳輸層協(xié)議的異步通信
asynchat asyncore 的增強(qiáng)版
cg 基本的 CGI(Common Gateway Interface,早期開發(fā)動(dòng)態(tài)網(wǎng)站的技術(shù))支持
email E-mail 和 MLME 消息處理模塊
ftplib 支持 FTP 協(xié)議的客戶端模塊
httplib、http.client 支持 HTTP 協(xié)議以及 HTTP 客戶揣的模塊
imaplib 支持 IMAP4 協(xié)議的客戶端模塊
mailbox 操作不同格式郵箱的模塊
mailcap 支持 Mailcap 文件處理的模塊
nntplib 支持 NTTP 協(xié)議的客戶端模塊
smtplib 支持 SMTP 協(xié)議(發(fā)送郵件)的客戶端模塊
poplib 支持 POP3 協(xié)議的客戶端模塊
telnetlib 支持TELNET 協(xié)議的客戶端模塊
urllib及其子模塊 支持URL 處理的模塊
xmlrpc、xmlrpc.server、xmlrpc.client 支持XML-RPC協(xié)議的服務(wù)器端和客戶端模塊

三、Python socket建立TCP連接

程序在使用 socket 之前,必須先創(chuàng)建 socket 對(duì)象,可通過該類的如下構(gòu)造器來創(chuàng)建 socket 實(shí)例:

socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)

  1. family 參數(shù)用于指定網(wǎng)絡(luò)類型。該參數(shù)支持 socket.AF_UNIX(UNIX 網(wǎng)絡(luò))、socket.AF_INET(基于 IPv4 協(xié)議的網(wǎng)絡(luò))和 socket.AF_INET6(基于 IPv6 協(xié)議的網(wǎng)絡(luò))這三個(gè)常量。
  2. type 參數(shù)用于指定網(wǎng)絡(luò) Sock 類型。該參數(shù)可支持 SOCK_STREAM(默認(rèn)值,創(chuàng)建基于 TCP 協(xié)議的 socket)、SOCK_DGRAM(創(chuàng)建基于 UDP 協(xié)議的 socket)和 SOCK_RAW(創(chuàng)建原始 socket)。
  3. proto 參數(shù)用于指定協(xié)議號(hào),如果沒有特殊要求,該參數(shù)默認(rèn)為 0 ,并可以忽略。

作為服務(wù)器端使用的 socket 必須被綁定到指定 IP 地址和端口,并在該 IP 地址和端口進(jìn)行監(jiān)聽,接收來自客戶端的連接。 TCP 通信的服務(wù)器端編程的基本步驟:

  • 服務(wù)器端先創(chuàng)建一個(gè) socket 對(duì)象(socket.socket())。
  • 服務(wù)器端 socket 將自己綁定到指定 IP 地址和端口(socket.bind(address,host))。
  • 服務(wù)器端 socket 調(diào)用 listen() 方法監(jiān)聽網(wǎng)絡(luò)。
  • 程序采用循環(huán)不斷調(diào)用 socket 的 accept() 方法接收來自客戶端的連接。
  • 發(fā)送數(shù)據(jù):使用 send() 方法。注意,sendto() 方法用于 UDP 協(xié)議的通信。
# 導(dǎo)入 socket 模塊
import socket
# 創(chuàng)建socket對(duì)象
s = socket.socket()
# 將socket綁定到本機(jī)IP和端口
s.bind(('192.168.1.88', 30000))
# 服務(wù)端開始監(jiān)聽來自客戶端的連接
s.listen()
while True:
    # 每當(dāng)接收到客戶端socket的請(qǐng)求時(shí),該方法返回對(duì)應(yīng)的socket和遠(yuǎn)程地址
    c, addr = s.accept()
    print(c)
    print('連接地址:', addr)
    c.send('您好,您收到了服務(wù)器的新年祝福!'.encode('utf-8'))
    # 關(guān)閉連接
    c.close()

作為客戶端先創(chuàng)建一個(gè) socket 對(duì)象,然后調(diào)用 socket 的 connect() 方法建立與服務(wù)器端的連接,這樣就可以建立一個(gè)基于 TCP 協(xié)議的網(wǎng)絡(luò)連接。TCP 通信的客戶端編程的基本步驟大致歸納如下:

  • 客戶端先創(chuàng)建一個(gè) socket 對(duì)象(socket.socket())。
  • 客戶端 socket 調(diào)用 connect() 方法連接遠(yuǎn)程服務(wù)器。
  • 接收數(shù)據(jù):使用 recv() 方法。
# 導(dǎo)入socket模塊
import socket
# 創(chuàng)建socket對(duì)象
s = socket.socket()
# 連接遠(yuǎn)程主機(jī)
s.connect(('192.168.1.88', 30000))    # ①
print('--%s--' % s.recv(1024).decode('utf-8'))
s.close()

四、Python socket建立UDP連接

UDP協(xié)議,全稱 User Datagram Protocol,中文名稱為用戶數(shù)據(jù)報(bào)協(xié)議,主要用來支持那些需要在計(jì)算機(jī)之間傳輸數(shù)據(jù)的網(wǎng)絡(luò)連接。
UDP 是一種面向非連接的協(xié)議,面向非連接指的是在正式通信前不必與對(duì)方先建立連接,不管對(duì)方狀態(tài)就直接發(fā)送數(shù)據(jù)。至于對(duì)方是否可以接收到這些數(shù)據(jù),UDP 協(xié)議無法控制,所以說 UDP 是一種不可靠的協(xié)議。

UDP 協(xié)議和 TCP 協(xié)議簡(jiǎn)單對(duì)比如下:

  • TCP 協(xié)議:可靠,傳輸大小無限制,但是需要連接建立時(shí)間,差錯(cuò)控制開銷大。
  • UDP 協(xié)議:不可靠,差錯(cuò)控制開銷較小,傳輸大小限制在 64 KB以下,不需要建立連接。
  • UDP 在通信實(shí)例的兩端各建立一個(gè) socket,但它們只是發(fā)送、接收數(shù)據(jù)的對(duì)象,沒有客戶端和服務(wù)器端的概念

socket建立UDP連接
程序在創(chuàng)建 socket 時(shí),可通過 type 參數(shù)指定該 socket 的類型,如果將該參數(shù)指定為 SOCK_DGRAM,則意味著創(chuàng)建基于 UDP 協(xié)議的 socket。程序可以通過如下兩個(gè)方法來發(fā)送和接收數(shù)據(jù):

  • socket.sendto(bytes, address):將 bytes 數(shù)據(jù)發(fā)送到 address 地址。
  • socket.recvfrom(bufsize[, flags]):接收數(shù)據(jù)。該方法可以同時(shí)返回 socket 中的數(shù)據(jù)和數(shù)據(jù)來源地址。

使用 UDP 協(xié)議的 socket 在發(fā)送數(shù)據(jù)時(shí)必須使用 sendto() 方法,這是因?yàn)槌绦虮仨氈付òl(fā)送數(shù)據(jù)的目標(biāo)地址
使用 UDP 協(xié)議的 socket 在接收數(shù)據(jù)時(shí),既可使用普通的 recv() 方法,也可使用 recvfrom() 方法。如果程序需要得到數(shù)據(jù)報(bào)的來源,則應(yīng)該使用 recvfrom() 方法

作為服務(wù)器端使用的 socket

import socket
PORT = 30000;
# 定義每個(gè)數(shù)據(jù)報(bào)的大小最大為4KB
DATA_LEN = 4096;
# 定義一個(gè)字符串?dāng)?shù)組,服務(wù)器端發(fā)送該數(shù)組的元素
books = ("瘋狂Python講義",
    "瘋狂Kotlin講義",
    "瘋狂Android講義",
    "瘋狂Swift講義")
# 通過type屬性指定創(chuàng)建基于UDP協(xié)議的socket
s = socket.socket(type=socket.SOCK_DGRAM)
# 將該socket綁定到本機(jī)的指定IP和端口
s.bind(('192.168.199.1', PORT))
# 采用循環(huán)接收數(shù)據(jù)
for i in range(1000):
    # 讀取s中的數(shù)據(jù)的數(shù)據(jù)的發(fā)送地址
    data, addr = s.recvfrom(DATA_LEN)
    # 將接收到的內(nèi)容轉(zhuǎn)換成字符串后輸出
    print(data.decode('utf-8'),addr)
    # 從字符串?dāng)?shù)組中取出一個(gè)元素作為發(fā)送數(shù)據(jù)
    send_data = books[i % 4].encode('utf-8')
    # 將數(shù)據(jù)報(bào)發(fā)送給addr地址
    s.sendto(send_data, addr)
s.close()

作為客戶端使用的 socket

import socket
PORT = 30000;
# 定義每個(gè)數(shù)據(jù)報(bào)的大小最大為4KB
DATA_LEN = 4096;
DEST_IP = "192.168.199.1";
# 通過type屬性指定創(chuàng)建基于UDP協(xié)議的socket
s = socket.socket(type=socket.SOCK_DGRAM)
# 不斷地讀取鍵盤輸入
while True:
    line = input('')
    if line is None or line == 'exit':
        break
    data = line.encode('utf-8')
    # 發(fā)送數(shù)據(jù)報(bào)
    s.sendto(data, (DEST_IP, PORT))
    # 讀取socket中的數(shù)據(jù)
    data = s.recv(DATA_LEN)
    print(data.decode('utf-8'))
s.close()

五、Python smtplib模塊:發(fā)送郵件

使用 Python 的 smtplib 模塊來發(fā)送郵件非常簡(jiǎn)單,只需要按照如下 3 步來發(fā)送郵件即可:

  1. 連接 SMTP 服務(wù)器,并使用用戶名、密碼登錄服務(wù)器。
  2. 創(chuàng)建 EmailMessage 對(duì)象,該對(duì)象代表郵件本身。
  3. 調(diào)用代表與 SMTP 服務(wù)器連接的對(duì)象的 sendmail() 方法發(fā)送郵件。
  4. 要為郵件設(shè)置主題、發(fā)件人名字和收件人名字,需要設(shè)置 EmailMessage 對(duì)象的相應(yīng)屬性。
  5. 要將郵件改為 HTML ,需要調(diào)用 EmailMessage的set_content() 方法的第二個(gè)參數(shù),設(shè)置為 html。
import smtplib
from email.message import EmailMessage

smtp_server = 'smtp.qq.com'    # 定義SMTP服務(wù)器地址:
from_addr = '425144880@qq.com'    # 定義發(fā)件人地址
password = '123456'    # 定義登錄郵箱的密碼
to_addr = 'wozhufuni999@163.com'    # 定義收件人地址
# 創(chuàng)建SMTP連接
#conn = smtplib.SMTP(smtp_server, 25)
conn = smtplib.SMTP_SSL(smtp_server,465)
conn.set_debuglevel(1)    # smtplib 調(diào)試模式
conn.login(from_addr, password)
first_id = '0000001'
# 創(chuàng)建郵件對(duì)象
msg = EmailMessage()
# 設(shè)置郵件內(nèi)容
msg.set_content('<h2>郵件內(nèi)容</h2>'
'<p>您好,這是一封來自Python的郵件<p>'
'<img src="cid:' + first_id +'"><p>'
'來自<a html', 'utf-8')
msg['subject'] = '一封HTML郵件'
msg['from'] = '田翔<%s>' % from_addr
msg['to'] = '新用戶 <%s>' % to_addr
with open('E:/logo.jpg', 'rb') as f:
    # 添加附件
    msg.add_attachment(f.read(), maintype='image',
        subtype='jpeg', filename='test.png', cid=first_id)
# 發(fā)送郵件
conn.sendmail(from_addr, [to_addr], msg.as_string())
# 退出連接
conn.quit()

為了給郵件添加附件,只需調(diào)用 EmailMessage的add_attachment() 方法即可。該方法支持很多參數(shù),最常見的參數(shù)如下:
maintype:指定附件的主類型。比如指定 image 代表附件是圖片。
subtype:指定附件的子類型。比如指定為 png,代表附件是 PNG 圖片。一般來說,子類型受主類型的限制。
filename:指定附件的文件名。
cid=img:指定附件的資源 ID,郵件正文可通過資源 ID 來引用該資源。

六、Python poplib模塊:收取郵件

使用 poplib 收取郵件可分為兩步:

  1. 使用 poplib.POP3 或 poplib.POP3_SSL 按 POP3 協(xié)議從服務(wù)器端下載郵件。
  2. 使用 email.parser.Parser 或 email.parser.BytesParser 解析郵件內(nèi)容,得到 EmailMessage 對(duì)象,從 EmailMessage 對(duì)象中讀取郵件內(nèi)容。
import poplib, os.path, mimetypes
from email.parser import BytesParser, Parser
from email.policy import default
# 輸入郵件地址, 口令和POP3服務(wù)器地址:
email = 'tx@henghaodata.com'
password = '123456'
pop3_server = 'pop-ent.21cn.com'
# 連接到POP 3服務(wù)器:
#conn = poplib.POP3(pop3_server, 110)
conn = poplib.POP3_SSL(pop3_server, 995)
# 可以打開或關(guān)閉調(diào)試信息:
#conn.set_debuglevel(1)
# 可選:打印POP 3服務(wù)器的歡迎文字:
print(conn.getwelcome().decode('utf-8'))
# 輸入用戶名、密碼信息
# 相當(dāng)于發(fā)送POP 3的user命令
conn.user(email)
# 相當(dāng)于發(fā)送POP 3的pass命令
conn.pass_(password)
# 獲取郵件統(tǒng)計(jì)信息,相當(dāng)于發(fā)送POP 3的stat命令
message_num, total_size = conn.stat()
print('郵件數(shù): %s. 總大小: %s' % (message_num, total_size))
# 獲取服務(wù)器上的郵件列表,相當(dāng)于發(fā)送POP 3的list命令
# resp保存服務(wù)器的響應(yīng)碼
# mails列表保存每封郵件的編號(hào)、大小
resp, mails, octets = conn.list()
print(resp, mails)
# 獲取指定郵件的內(nèi)容(此處傳入總長(zhǎng)度,也就是獲取最后一封郵件)
# 相當(dāng)于發(fā)送POP 3的retr命令
# resp保存服務(wù)器的響應(yīng)碼
# data保存該郵件的內(nèi)容
resp, data, octets  = conn.retr(len(mails))
# 將data的所有數(shù)據(jù)(原本是一個(gè)字節(jié)列表)拼接在一起
msg_data = b'\r\n'.join(data)
# 將字符串內(nèi)容解析成郵件,此處一定要指定policy=default
msg = BytesParser(policy=default).parsebytes(msg_data)       #①
print(type(msg))
print('發(fā)件人:' + msg['from'])
print('收件人:' + msg['to'])
print('主題:' + msg['subject'])
print('第一個(gè)收件人名字:' + msg['to'].addresses[0].username)
print('第一個(gè)發(fā)件人名字:' + msg['from'].addresses[0].username)
for part in msg.walk():
    counter = 1
    # 如果maintype是multipart,說明是容器(用于包含正文、附件等)
    if part.get_content_maintype() == 'multipart' :
        continue
    # 如果maintype是multipart,說明是郵件正文部分
    elif part.get_content_maintype() == 'text':
        print(part.get_content())
    # 處理附件
    else :
        # 獲取附件的文件名
        filename = part.get_filename()
        # 如果沒有文件名,程序要負(fù)責(zé)為附件生成文件名
        if not filename:
            # 根據(jù)附件的contnet_type來推測(cè)它的后綴名
            ext = mimetypes.guess_extension(part.get_content_type())
            # 如果推測(cè)不出后綴名
            if not ext:
                # 使用.bin作為后綴名
                ext = '.bin'
            # 程序?yàn)楦郊砩晌募?            filename = 'part-%03d%s' % (counter, ext)
        counter += 1
        # 將附件寫入的本地文件
        with open(os.path.join('.', filename), 'wb') as fp:
            fp.write(part.get_payload(decode=True))
# 退出服務(wù)器,相當(dāng)于發(fā)送POP 3的quit命令
conn.quit()

上面程序通過 poplib 模塊使用 POP3 命令從服務(wù)器端下載郵件,其實(shí)就是依次發(fā)送 user、pass、stat、list、retr 命令的過程。當(dāng) retr 命令執(zhí)行完成后,將得到最后一封郵件的數(shù)據(jù) data,該 data 是一個(gè) list 列表,因此程序需要先將這些數(shù)據(jù)拼接成一個(gè)整體,然后將郵件數(shù)據(jù)恢復(fù)成 EmailMessage 對(duì)象。這里有一點(diǎn)需要指出,程序在創(chuàng)建 BytesParser(解析字節(jié)串格式的郵件數(shù)據(jù))或 Parser(解析字符串格式的郵件數(shù)據(jù))時(shí),必須指定 policy=default

如果程序要讀取 EmailMessage 的各部分,則需要調(diào)用該對(duì)象的 walk() 方法,該方法返回一個(gè)可迭代對(duì)象,程序使用 for 循環(huán)遍歷 walk() 方法的返回值,對(duì)郵件內(nèi)容進(jìn)行逐項(xiàng)處理:

  1. 如果郵件某項(xiàng)的 maintype 是 'multipart',則說明這一項(xiàng)是容器,用于包含郵件內(nèi)容、附件等其他項(xiàng)。
  2. 如果郵件某項(xiàng)的 maintype 是 'text',則說明這一項(xiàng)的內(nèi)容是文本,通常就是郵件正文或文本附件。對(duì)于這種文本內(nèi)容,程序直接將其輸出到控制臺(tái)中。
  3. 如果郵件某項(xiàng)的 maintype 是其他,則說明這一項(xiàng)的內(nèi)容是附件,程序?qū)⒏郊?nèi)容保存在本地文件中。

運(yùn)行上面程序,可以看到程序收取了指定郵件的最后一封郵件,并將郵件內(nèi)容輸出到控制臺(tái)中,將郵件附件保存在本地文件中。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 網(wǎng)絡(luò)編程 一.楔子 你現(xiàn)在已經(jīng)學(xué)會(huì)了寫python代碼,假如你寫了兩個(gè)python文件a.py和b.py,分別去運(yùn)...
    go以恒閱讀 2,248評(píng)論 0 6
  • 計(jì)算機(jī)網(wǎng)絡(luò)概述 網(wǎng)絡(luò)編程的實(shí)質(zhì)就是兩個(gè)(或多個(gè))設(shè)備(例如計(jì)算機(jī))之間的數(shù)據(jù)傳輸。 按照計(jì)算機(jī)網(wǎng)絡(luò)的定義,通過一定...
    蛋炒飯_By閱讀 1,369評(píng)論 0 10
  • 網(wǎng)絡(luò)概念第一天 兩臺(tái)電腦怎么通過網(wǎng)絡(luò)傳輸數(shù)據(jù)?怎樣才能知道傳輸?shù)氖菙?shù)據(jù)?誰摸過網(wǎng)線? 看電影,怎么看的?通過電流,...
    小吖朱閱讀 1,648評(píng)論 0 1
  • 網(wǎng)絡(luò) 理論模型,分為七層物理層數(shù)據(jù)鏈路層傳輸層會(huì)話層表示層應(yīng)用層 實(shí)際應(yīng)用,分為四層鏈路層網(wǎng)絡(luò)層傳輸層應(yīng)用層 IP...
    FlyingLittlePG閱讀 966評(píng)論 0 0
  • 她媽的 本寶寶又沒占你便宜 你哪兒來的勇氣 竟對(duì)我頤指氣使,指手畫腳。 本寶寶表示醉醉的 看見本寶寶不耐煩的小眼神...
    小H_a09f閱讀 104評(píng)論 0 0

友情鏈接更多精彩內(nèi)容