Python網(wǎng)絡(luò)編程基礎(chǔ)

原文轉(zhuǎn)自Python教程

TCP/IP簡介
雖然大家現(xiàn)在對互聯(lián)網(wǎng)很熟悉畏梆,但是計(jì)算機(jī)網(wǎng)絡(luò)的出現(xiàn)比互聯(lián)網(wǎng)要早很多蟹腾。

計(jì)算機(jī)為了聯(lián)網(wǎng)煌珊,就必須規(guī)定通信協(xié)議私杜,早期的計(jì)算機(jī)網(wǎng)絡(luò)蚕键,都是由各廠商自己規(guī)定一套協(xié)議,IBM衰粹、Apple和Microsoft都有各自的網(wǎng)絡(luò)協(xié)議锣光,互不兼容,這就好比一群人有的說英語铝耻,有的說中文誊爹,有的說德語,說同一種語言的人可以交流瓢捉,不同的語言之間就不行了频丘。為了把全世界的所有不同類型的計(jì)算機(jī)都連接起來,就必須規(guī)定一套全球通用的協(xié)議泡态,為了實(shí)現(xiàn)互聯(lián)網(wǎng)這個(gè)目標(biāo)搂漠,互聯(lián)網(wǎng)協(xié)議簇(Internet Protocol Suite)就是通用協(xié)議標(biāo)準(zhǔn)。Internet是由inter和net兩個(gè)單詞組合起來的某弦,原意就是連接“網(wǎng)絡(luò)”的網(wǎng)絡(luò)状答,有了Internet,任何私有網(wǎng)絡(luò)刀崖,只要支持這個(gè)協(xié)議,就可以聯(lián)入互聯(lián)網(wǎng)拍摇。

因?yàn)榛ヂ?lián)網(wǎng)協(xié)議包含了上百種協(xié)議標(biāo)準(zhǔn)亮钦,但是最重要的兩個(gè)協(xié)議是TCP和IP協(xié)議,所以充活,大家把互聯(lián)網(wǎng)的協(xié)議簡稱TCP/IP協(xié)議蜂莉。
通信的時(shí)候,雙方必須知道對方的標(biāo)識混卵,好比發(fā)郵件必須知道對方的郵件地址映穗。互聯(lián)網(wǎng)上每個(gè)計(jì)算機(jī)的唯一標(biāo)識就是IP地址幕随,類似123.123.123.123蚁滋。如果一臺計(jì)算機(jī)同時(shí)接入到兩個(gè)或更多的網(wǎng)絡(luò),比如路由器,它就會有兩個(gè)或多個(gè)IP地址辕录,所以睦霎,IP地址對應(yīng)的實(shí)際上是計(jì)算機(jī)的網(wǎng)絡(luò)接口,通常是網(wǎng)卡走诞。

IP協(xié)議負(fù)責(zé)把數(shù)據(jù)從一臺計(jì)算機(jī)通過網(wǎng)絡(luò)發(fā)送到另一臺計(jì)算機(jī)副女。數(shù)據(jù)被分割成一小塊一小塊,然后通過IP包發(fā)送出去蚣旱。由于互聯(lián)網(wǎng)鏈路復(fù)雜碑幅,兩臺計(jì)算機(jī)之間經(jīng)常有多條線路,因此塞绿,路由器就負(fù)責(zé)決定如何把一個(gè)IP包轉(zhuǎn)發(fā)出去沟涨。IP包的特點(diǎn)是按塊發(fā)送,途徑多個(gè)路由位隶,但不保證能到達(dá)拷窜,也不保證順序到達(dá)。

IP協(xié)議示意

IP地址實(shí)際上是一個(gè)32位整數(shù)(稱為IPv4)涧黄,以字符串表示的IP地址如192.168.0.1實(shí)際上是把32位整數(shù)按8位分組后的數(shù)字表示篮昧,目的是便于閱讀。IPv6地址實(shí)際上是一個(gè)128位整數(shù)笋妥,它是目前使用的IPv4的升級版懊昨,以字符串表示類似于2001:0db8:85a3:0042:1000:8a2e:0370:7334.

TCP協(xié)議則是建立在IP協(xié)議之上的。TCP協(xié)議負(fù)責(zé)在兩臺計(jì)算機(jī)之間建立可靠連接春宣,保證數(shù)據(jù)包按順序到達(dá)酵颁。TCP協(xié)議會通過握手建立連接,然后月帝,對每個(gè)IP包編號躏惋,確保對方按順序收到,如果包丟掉了嚷辅,就自動重發(fā)簿姨。
許多常用的更高級的協(xié)議都是建立在TCP協(xié)議基礎(chǔ)上的,比如用于瀏覽器的HTTP協(xié)議簸搞、發(fā)送郵件的SMTP協(xié)議等扁位。

一個(gè)IP包除了包含要傳輸?shù)臄?shù)據(jù)外,還包含源IP地址和目標(biāo)IP地址趁俊,源端口和目標(biāo)端口域仇。

端口有什么作用?在兩臺計(jì)算機(jī)通信時(shí)寺擂,只發(fā)IP地址是不夠的暇务,因?yàn)橥慌_計(jì)算機(jī)上跑著多個(gè)網(wǎng)絡(luò)程序泼掠。一個(gè)IP包來了之后,到底是交給瀏覽器還是QQ般卑,就需要端口號來區(qū)分武鲁。每個(gè)網(wǎng)絡(luò)程序都向操作系統(tǒng)申請唯一的端口號,這樣蝠检,兩個(gè)進(jìn)程在兩臺計(jì)算機(jī)之間建立網(wǎng)絡(luò)連接就需要各自的IP地址和各自的端口號沐鼠。
一個(gè)進(jìn)程也可能同時(shí)與多個(gè)計(jì)算機(jī)建立鏈接,因此它會申請很多端口叹谁。
了解了TCP/IP協(xié)議的基本概念饲梭,IP地址和端口的概念,我們就可以開始進(jìn)行網(wǎng)絡(luò)編程了焰檩。

TCP編程

Socket是網(wǎng)絡(luò)編程的一個(gè)抽象概念憔涉。通常我們用一個(gè)Socket表示“打開了一個(gè)網(wǎng)絡(luò)鏈接”,而打開一個(gè)Socket需要知道目標(biāo)計(jì)算機(jī)的IP地址和端口號析苫,再指定協(xié)議類型即可兜叨。

客戶端
大多數(shù)連接都是可靠的TCP連接。創(chuàng)建TCP連接時(shí)衩侥,主動發(fā)起連接的叫客戶端国旷,被動響應(yīng)連接的叫服務(wù)器。

舉個(gè)例子茫死,當(dāng)我們在瀏覽器中訪問新浪時(shí)跪但,我們自己的計(jì)算機(jī)就是客戶端,瀏覽器會主動向新浪的服務(wù)器發(fā)起連接峦萎。如果一切順利屡久,新浪的服務(wù)器接受了我們的連接,一個(gè)TCP連接就建立起來的爱榔,后面的通信就是發(fā)送網(wǎng)頁內(nèi)容了被环。

所以,我們要創(chuàng)建一個(gè)基于TCP連接的Socket详幽,可以這樣做:

# 導(dǎo)入socket庫:

import socket

# 創(chuàng)建一個(gè)socket:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 建立連接:

s.connect(('www.sina.com.cn', 80))


創(chuàng)建Socket時(shí)蛤售,AF_INET指定使用IPv4協(xié)議,如果要用更先進(jìn)的IPv6妒潭,就指定為AF_INET6。SOCK_STREAM指定使用面向流的TCP協(xié)議揣钦,這樣雳灾,一個(gè)Socket對象就創(chuàng)建成功,但是還沒有建立連接冯凹。

客戶端要主動發(fā)起TCP連接谎亩,必須知道服務(wù)器的IP地址和端口號炒嘲。新浪網(wǎng)站的IP地址可以用域名www.sina.com.cn自動轉(zhuǎn)換到IP地址,但是怎么知道新浪服務(wù)器的端口號呢匈庭?

答案是作為服務(wù)器夫凸,提供什么樣的服務(wù),端口號就必須固定下來阱持。由于我們想要訪問網(wǎng)頁夭拌,因此新浪提供網(wǎng)頁服務(wù)的服務(wù)器必須把端口號固定在80
端口,因?yàn)?0端口是Web服務(wù)的標(biāo)準(zhǔn)端口衷咽。其他服務(wù)都有對應(yīng)的標(biāo)準(zhǔn)端口號鸽扁,例如SMTP服務(wù)是25端口,F(xiàn)TP服務(wù)是21端口镶骗,等等桶现。端口號小于1024的是Internet標(biāo)準(zhǔn)服務(wù)的端口,端口號大于1024的鼎姊,可以任意使用骡和。

因此,我們連接新浪服務(wù)器的代碼如下:

s.connect(('www.sina.com.cn', 80))

注意參數(shù)是一個(gè)tuple相寇,包含地址和端口號慰于。建立TCP連接后,我們就可以向新浪服務(wù)器發(fā)送請求裆赵,要求返回首頁的內(nèi)容:

# 發(fā)送數(shù)據(jù):
s.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')

TCP連接創(chuàng)建的是雙向通道东囚,雙方都可以同時(shí)給對方發(fā)數(shù)據(jù)。但是誰先發(fā)誰后發(fā)战授,怎么協(xié)調(diào)页藻,要根據(jù)具體的協(xié)議來決定。例如植兰,HTTP協(xié)議規(guī)定客戶端必須先發(fā)請求給服務(wù)器份帐,服務(wù)器收到后才發(fā)數(shù)據(jù)給客戶端。

發(fā)送的文本格式必須符合HTTP標(biāo)準(zhǔn)楣导,如果格式?jīng)]問題废境,接下來就可以接收新浪服務(wù)器返回的數(shù)據(jù)了:

# 接收數(shù)據(jù):
buffer = []
while True:
    # 每次最多接收1k字節(jié):
    d = s.recv(1024)
    if d:
        buffer.append(d)
    else:
        break
data = b''.join(buffer)

接收數(shù)據(jù)時(shí),調(diào)用recv(max)方法筒繁,一次最多接收指定的字節(jié)數(shù)噩凹,因此,在一個(gè)while循環(huán)中反復(fù)接收毡咏,直到recv()返回空數(shù)據(jù)驮宴,表示接收完畢,退出循環(huán)呕缭。

當(dāng)我們接收完數(shù)據(jù)后堵泽,調(diào)用close()方法關(guān)閉Socket修己,這樣,一次完整的網(wǎng)絡(luò)通信就結(jié)束了:

# 關(guān)閉連接:s.close()

接收到的數(shù)據(jù)包括HTTP頭和網(wǎng)頁本身迎罗,我們只需要把HTTP頭和網(wǎng)頁分離一下睬愤,把HTTP頭打印出來,網(wǎng)頁內(nèi)容保存到文件:

header, html = data.split(b'\r\n\r\n', 1)

print(header.decode('utf-8'))

# 把接收的數(shù)據(jù)寫入文件:

with open('sina.html', 'wb') as f:

    f.write(html)

現(xiàn)在纹安,只需要在瀏覽器中打開這個(gè)sina.html文件尤辱,就可以看到新浪的首頁了。

服務(wù)器
和客戶端編程相比钻蔑,服務(wù)器編程就要復(fù)雜一些啥刻。
服務(wù)器進(jìn)程首先要綁定一個(gè)端口并監(jiān)聽來自其他客戶端的連接。如果某個(gè)客戶端連接過來了咪笑,服務(wù)器就與該客戶端建立Socket連接可帽,隨后的通信就靠這個(gè)Socket連接了。

所以窗怒,服務(wù)器會打開固定端口(比如80)監(jiān)聽映跟,每來一個(gè)客戶端連接,就創(chuàng)建該Socket連接扬虚。由于服務(wù)器會有大量來自客戶端的連接努隙,所以,服務(wù)器要能夠區(qū)分一個(gè)Socket連接是和哪個(gè)客戶端綁定的辜昵。一個(gè)Socket依賴4項(xiàng):服務(wù)器地址荸镊、服務(wù)器端口、客戶端地址堪置、客戶端端口來唯一確定一個(gè)Socket躬存。
但是服務(wù)器還需要同時(shí)響應(yīng)多個(gè)客戶端的請求,所以舀锨,每個(gè)連接都需要一個(gè)新的進(jìn)程或者新的線程來處理岭洲,否則,服務(wù)器一次就只能服務(wù)一個(gè)客戶端了坎匿。
我們來編寫一個(gè)簡單的服務(wù)器程序盾剩,它接收客戶端連接,把客戶端發(fā)過來的字符串加上Hello再發(fā)回去替蔬。

首先告私,創(chuàng)建一個(gè)基于IPv4和TCP協(xié)議的Socket:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

然后,我們要綁定監(jiān)聽的地址和端口承桥。服務(wù)器可能有多塊網(wǎng)卡驻粟,可以綁定到某一塊網(wǎng)卡的IP地址上,也可以用0.0.0.0綁定到所有的網(wǎng)絡(luò)地址快毛,還可以用127.0.0.1綁定到本機(jī)地址格嗅。127.0.0.1是一個(gè)特殊的IP地址,表示本機(jī)地址唠帝,如果綁定到這個(gè)地址屯掖,客戶端必須同時(shí)在本機(jī)運(yùn)行才能連接,也就是說襟衰,外部的計(jì)算機(jī)無法連接進(jìn)來贴铜。
端口號需要預(yù)先指定。因?yàn)槲覀儗懙倪@個(gè)服務(wù)不是標(biāo)準(zhǔn)服務(wù)瀑晒,所以用9999這個(gè)端口號绍坝。請注意,小于1024的端口號必須要有管理員權(quán)限才能綁定:

# 監(jiān)聽端口:s.bind(('127.0.0.1', 9999))

緊接著苔悦,調(diào)用listen()方法開始監(jiān)聽端口轩褐,傳入的參數(shù)指定等待連接的最大數(shù)量:

s.listen(5)
print('Waiting for connection...')

接下來,服務(wù)器程序通過一個(gè)永久循環(huán)來接受來自客戶端的連接玖详,accept()
會等待并返回一個(gè)客戶端的連接:

while True:

    # 接受一個(gè)新連接:

    sock, addr = s.accept()

    # 創(chuàng)建新線程來處理TCP連接:

    t = threading.Thread(target=tcplink, args=(sock, addr))

    t.start()


每個(gè)連接都必須創(chuàng)建新線程(或進(jìn)程)來處理把介,否則,單線程在處理連接的過程中蟋座,無法接受其他客戶端的連接:

def tcplink(sock, addr):

    print('Accept new connection from %s:%s...' % addr)

    sock.send(b'Welcome!')

    while True:

        data = sock.recv(1024)

        time.sleep(1)

        if not data or data.decode('utf-8') == 'exit':

            break

        sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))

    sock.close()

    print('Connection from %s:%s closed.' % addr)


連接建立后拗踢,服務(wù)器首先發(fā)一條歡迎消息,然后等待客戶端數(shù)據(jù)向臀,并加上Hello再發(fā)送給客戶端巢墅。如果客戶端發(fā)送了exit字符串,就直接關(guān)閉連接券膀。
要測試這個(gè)服務(wù)器程序君纫,我們還需要編寫一個(gè)客戶端程序:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 建立連接:

s.connect(('127.0.0.1', 9999))

# 接收歡迎消息:

print(s.recv(1024).decode('utf-8'))

for data in [b'Michael', b'Tracy', b'Sarah']:

    # 發(fā)送數(shù)據(jù):

    s.send(data)

    print(s.recv(1024).decode('utf-8'))

s.send(b'exit')

s.close()


我們需要打開兩個(gè)命令行窗口,一個(gè)運(yùn)行服務(wù)器程序三娩,另一個(gè)運(yùn)行客戶端程序庵芭,就可以看到效果了:

運(yùn)行結(jié)果

需要注意的是,客戶端程序運(yùn)行完畢就退出了雀监,而服務(wù)器程序會永遠(yuǎn)運(yùn)行下去双吆,必須按Ctrl+C退出程序。

小結(jié)
用TCP協(xié)議進(jìn)行Socket編程在Python中十分簡單会前,對于客戶端好乐,要主動連接服務(wù)器的IP和指定端口,對于服務(wù)器瓦宜,要首先監(jiān)聽指定端口蔚万,然后,對每一個(gè)新的連接临庇,創(chuàng)建一個(gè)線程或進(jìn)程來處理反璃。通常昵慌,服務(wù)器程序會無限運(yùn)行下去。
同一個(gè)端口淮蜈,被一個(gè)Socket綁定了以后斋攀,就不能被別的Socket綁定了。
源碼:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
# 創(chuàng)建一個(gè)socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立連接:
s.connect(('www.sina.com.cn', 80))
# 發(fā)送數(shù)據(jù):
s.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')
# 接收數(shù)據(jù):

buffer = []
while True:
    # 每次最多接收1k字節(jié):
    d = s.recv(1024)
    if d
        buffer.append(d)
    else:
        break
data = b''.join(buffer)
# 關(guān)閉連接:
s.close()
header, html = data.split(b'\r\n\r\n', 1)

print(header.decode('utf-8'))
# 把接收的數(shù)據(jù)寫入文件:
with open('sina.html', 'wb') as f:
    f.write(html)

UDP編程
TCP是建立可靠連接梧田,并且通信雙方都可以以流的形式發(fā)送數(shù)據(jù)淳蔼。相對TCP,UDP則是面向無連接的協(xié)議裁眯。

使用UDP協(xié)議時(shí)鹉梨,不需要建立連接,只需要知道對方的IP地址和端口號穿稳,就可以直接發(fā)數(shù)據(jù)包存皂。但是,能不能到達(dá)就不知道了司草。

雖然用UDP傳輸數(shù)據(jù)不可靠艰垂,但它的優(yōu)點(diǎn)是和TCP比,速度快埋虹,對于不要求可靠到達(dá)的數(shù)據(jù)猜憎,就可以使用UDP協(xié)議。

我們來看看如何通過UDP協(xié)議傳輸數(shù)據(jù)搔课。和TCP類似删铃,使用UDP的通信雙方也分為客戶端和服務(wù)器入问。服務(wù)器首先需要綁定端口:

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 綁定端口:

s.bind(('127.0.0.1', 9999))

創(chuàng)建Socket時(shí)融涣,SOCK_DGRAM指定了這個(gè)Socket的類型是UDP扒接。綁定端口和TCP一樣,但是不需要調(diào)用listen()方法袍啡,而是直接接收來自任何客戶端的數(shù)據(jù):

print('Bind UDP on 9999...')

while True:

    # 接收數(shù)據(jù):

    data, addr = s.recvfrom(1024)

    print('Received from %s:%s.' % addr)

    s.sendto(b'Hello, %s!' % data, addr)


recvfrom()方法返回?cái)?shù)據(jù)和客戶端的地址與端口踩官,這樣,服務(wù)器收到數(shù)據(jù)后境输,直接調(diào)用sendto()就可以把數(shù)據(jù)用UDP發(fā)給客戶端蔗牡。
注意這里省掉了多線程,因?yàn)檫@個(gè)例子很簡單嗅剖。
客戶端使用UDP時(shí)辩越,首先仍然創(chuàng)建基于UDP的Socket,然后信粮,不需要調(diào)用connect()黔攒,直接通過sendto()給服務(wù)器發(fā)數(shù)據(jù):

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', b'Tracy', b'Sarah']:
    # 發(fā)送數(shù)據(jù):
    s.sendto(data, ('127.0.0.1', 9999))
    # 接收數(shù)據(jù):
    print(s.recv(1024).decode('utf-8'))
s.close()

從服務(wù)器接收數(shù)據(jù)仍然調(diào)用recv()方法。仍然用兩個(gè)命令行分別啟動服務(wù)器和客戶端測試,結(jié)果如下:

結(jié)果

小結(jié)
UDP的使用與TCP類似督惰,但是不需要建立連接不傅。此外,服務(wù)器綁定UDP端口和TCP端口互不沖突赏胚,也就是說蛤签,UDP的9999端口與TCP的9999端口可以各自綁定。
sever.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定端口:

s.bind(('127.0.0.1', 9999))
print('Bind UDP on 9999...')
while True:
    # 接收數(shù)據(jù):
    data, addr = s.recvfrom(1024)
    print('Received from %s:%s.' % addr)
    reply = 'Hello, %s!' % data.decode('utf-8')
    s.sendto(reply.encode('utf-8'), addr)

client.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', b'Tracy', b'Sarah']:
    # 發(fā)送數(shù)據(jù):
    s.sendto(data, ('127.0.0.1', 9999))
    # 接收數(shù)據(jù):
    print(s.recv(1024).decode('utf-8'))
s.close()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末栅哀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子称龙,更是在濱河造成了極大的恐慌留拾,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鲫尊,死亡現(xiàn)場離奇詭異痴柔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)疫向,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門咳蔚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人搔驼,你說我怎么就攤上這事谈火。” “怎么了舌涨?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵糯耍,是天一觀的道長。 經(jīng)常有香客問我囊嘉,道長温技,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任扭粱,我火速辦了婚禮舵鳞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘俩滥。我一直安慰自己,他們只是感情好霜旧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著掷倔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凛虽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天糠聪,我揣著相機(jī)與錄音戳杀,去河邊找鬼。 笑死傍菇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的咐低。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼损痰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起爹袁,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤档址,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蠢涝,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惯吕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年堡距,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了搔体。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片半醉。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疚俱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缩多,到底是詐尸還是另有隱情衬吆,我是刑警寧澤梁钾,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站蟀架,受9級特大地震影響捌省,放射性物質(zhì)發(fā)生泄漏牙勘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一所禀、第九天 我趴在偏房一處隱蔽的房頂上張望恭金。 院中可真熱鬧,春花似錦褂策、人聲如沸横腿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耿焊。三九已至揪惦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間罗侯,已是汗流浹背器腋。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钩杰,地道東北人纫塌。 一個(gè)月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像讲弄,于是被迫代替她去往敵國和親措左。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容