CSAPP--第十一章:網(wǎng)絡(luò)編程

CSAPP--第十一章:網(wǎng)絡(luò)編程

客戶端-服務(wù)器模型

  • 網(wǎng)絡(luò)應(yīng)用都是基于客戶端-服務(wù)器模型却盘。
    一個應(yīng)用由一個服務(wù)器進(jìn)程和多個客戶端進(jìn)程構(gòu)成窘游。

    事務(wù):模型中的基本操作,包含四步:

    ①客戶端進(jìn)程發(fā)送請求

    ②服務(wù)器進(jìn)程接收請求寺庄,并與其存儲設(shè)備交互進(jìn)行處理艾蓝。

    ③服務(wù)器進(jìn)程發(fā)送響應(yīng)。

    ④客戶端進(jìn)程處理響應(yīng)斗塘。

    事務(wù)

    網(wǎng)絡(luò)

客戶端和服務(wù)端通常運(yùn)行在不同主機(jī)上赢织,通過計算機(jī)網(wǎng)絡(luò)的硬件和軟件來通信。

  • LAN(Local Area Network)

    局域網(wǎng)馍盟,其包含的主機(jī)位置范圍最小于置,通常在一個建筑內(nèi)。

    以太網(wǎng)(Ethernet): 現(xiàn)在最流行的局域網(wǎng)技術(shù)贞岭。

    局域網(wǎng)內(nèi)八毯,各主機(jī)通過集線器進(jìn)行連接。如下圖:


    網(wǎng)絡(luò)硬件組成
以太網(wǎng)段
  • 網(wǎng)橋(bridge):用于連接多個以太網(wǎng)段瞄桨,形成較大的局域網(wǎng)(橋接以太網(wǎng))话速。

    如下圖:

橋接以太網(wǎng)
  • WAN(Wide-Area network):

    廣域網(wǎng),其將不同局域網(wǎng)連接在一起芯侥,因?yàn)榈乩矸秶染钟蚓W(wǎng)大泊交,取名廣域網(wǎng)。

    如下圖:

小型互聯(lián)網(wǎng)絡(luò)

網(wǎng)絡(luò)協(xié)議

不同的主機(jī),其采用的局域網(wǎng)和廣域網(wǎng)技術(shù)可能不兼容活合,所以提出一個協(xié)議雏婶,消除主機(jī)間的通信障礙。

  • 協(xié)議功能:

    ①命名機(jī)制:采取同一套地址命名機(jī)制白指。

    ②傳送機(jī)制:定義一種通用的數(shù)據(jù)包:包頭 + 有效荷載留晚。包頭記載了源和目的主機(jī)的地址、及包大小等信息告嘲。

全球IP因特網(wǎng)

互聯(lián)網(wǎng)絡(luò)客戶端-服務(wù)器交互

  • TCP/IP協(xié)議(Transmission Control Protocol错维,傳輸控制協(xié)議 / Internet Protocol,互聯(lián)網(wǎng)絡(luò)協(xié)議)

    TCP/IP是一個協(xié)議簇橄唬,每個協(xié)議提供不同功能赋焕。TCP比IP更復(fù)雜。

    • IP協(xié)議:提供了基本命名方式和傳送機(jī)制仰楚。

      實(shí)現(xiàn)從一個主機(jī)隆判,往另一個主機(jī)傳送包,也稱數(shù)據(jù)報僧界。

      其對丟包不會試圖恢復(fù)侨嘀。

    • UDP協(xié)議(Unreliable Datagram Protocol,不可靠數(shù)據(jù)報協(xié)議)

    • TCP協(xié)議:構(gòu)建在IP協(xié)議之上的復(fù)雜協(xié)議捂襟,提供進(jìn)程間可靠的雙向連接咬腕。

      因特網(wǎng)應(yīng)用程序的軟件和硬件

  • IPv4、IPv6

    因特網(wǎng)協(xié)議版本4 (32位地址)

    1996年提出的因特網(wǎng)版本協(xié)議6 (128位地址):如今用戶還不多葬荷。

  • IP地址 //以下針對 IPv4

ip地址是32位無符號整數(shù)涨共。網(wǎng)絡(luò)程序?qū)p地址存放在:ip地址結(jié)構(gòu)中。

ps:其導(dǎo)致了麻煩的操作宠漩,每次使用要建立結(jié)構(gòu)體举反,再取其中的值,很麻煩:骞隆U罩!

struct in_addr{
    unit32_t  s_addr; /* 網(wǎng)絡(luò)字節(jié)順序中統(tǒng)一為大端順序 */
}瘦陈;

網(wǎng)絡(luò)字節(jié)順序(network byte order)為大端字節(jié)順序凝危。

所以對于小端機(jī)器中,會進(jìn)行字節(jié)順序(32位)轉(zhuǎn)換晨逝。

Unix提供的轉(zhuǎn)換函數(shù):

#inlcude<arpa/inet.h>
uint32_t  htonl(uint32_t  hostlong );   //host to network
uint16_t  htonl(uint16_t  hostshort ); 

uint32_t  ntohl(uint32_t  netlong );    //network to host
uint16_t  ntohl(uint16_t  netshort ); 

ps:沒有對應(yīng)的64位的函數(shù)蛾默。

  • 點(diǎn)分十進(jìn)制表示法

    用來表示ip地址的一種方法。

    如0x00000000 -> 0.0.0.0

    ? 二進(jìn)制 點(diǎn)分十進(jìn)制

    應(yīng)用程序通過inet_pton 捉貌、inet_ntop函數(shù)來實(shí)現(xiàn)轉(zhuǎn)換焚碌。

    #include<arpa/inet.h>
    int inet_pton(AF_INET, const char *src, void *dst);
                                //成功返回1,src非法時點(diǎn)分十進(jìn)制地址為0支竹,出錯為-1;
    const char *inet_ntop(AF_INET, const void *src, char *dst, socklen_t size);
                              //成功返回指向點(diǎn)分十進(jìn)制字符串的指針急前,錯誤為NULL
                          
    

    說明:以上兩個函數(shù)中,網(wǎng)絡(luò)地址的值是在結(jié)構(gòu)體中瀑构,所以要先設(shè)置結(jié)構(gòu)體裆针,然后取其中的值。

    編寫中出錯了蠻多寺晌。

    具體看linux 中的網(wǎng)絡(luò)編程文件夾下的ntop.c 世吨、 pton.c。

  • 因特網(wǎng)域名

    域名:一串用句號分隔的單詞(字母呻征、數(shù)字耘婚、破折號)。例如:www.baidu.com

    域名層次結(jié)構(gòu)(樹狀):

因特網(wǎng)域名層次結(jié)構(gòu)的部分

分為多層域名--

第一層為ICANN協(xié)會定義的陆赋,包括com沐祷、edu、gov攒岛、org戈轿、net等。

第二層為先到先分配的阵子。一個組織得到了二級域名后,就可以在子域(節(jié)點(diǎn)的子樹)中創(chuàng)建任何新的域名胜蛉。如:cmu.edu cs.cmu.edu

  • 域名挠进、IP地址映射

    1988年之前,都是用HOSTS.TXT的 文本文件來手工維護(hù)誊册。

    1988年后领突,通過世界范圍內(nèi)的數(shù)據(jù)庫DNS(Domain Name System:域名系統(tǒng))來維護(hù)。

    DNS數(shù)據(jù)庫:有上百萬條 主機(jī)條目結(jié)構(gòu) 組成案怯,每條主機(jī)條目結(jié)構(gòu)定義了一組域名和IP地址之間的映射君旦。

  • 映射關(guān)系:

    一對一 映射

    多個域名映射一個IP地址

    一個域名映射多個IP地址(同一組)

    多個域名映射同一組多個IP地址

  • 因特網(wǎng)連接

    因特網(wǎng)中,客戶端和服務(wù)器通過在連接上發(fā)送和接收字節(jié)流來通信嘲碱。

    從連接一對進(jìn)程而言金砍,其是:點(diǎn)對點(diǎn)的。

    從數(shù)據(jù)雙向流動而言麦锯,其是:全雙工的恕稠。

    • 套接字(socket):

      連接的一個端點(diǎn)。

      其內(nèi)容為IP地址加上16位的整數(shù)端口組成扶欣。(非硬件而是軟件端口)

      如:127.0.0.1:51212

    • 臨時端口(ephemeral port):

      當(dāng)客戶端發(fā)起連接請求時鹅巍,客戶端套接字地址中的端口千扶,是由內(nèi)核自動分配的。稱為臨時端口骆捧。

    • 知名端口:

      服務(wù)器中澎羞,套接字地址的端口常常是和服務(wù)綁定的,如web服務(wù)器通常使用端口80敛苇,電子郵件服務(wù)器通常使用端口25等妆绞。稱為知名端口。

    • 套接字對(socket pair):

      由連接兩端的套接字接谨,唯一確定摆碉。(cliaddr : cliport,servaddr:servport)


      網(wǎng)絡(luò)套接字
  • 套接字接口(socket inerface)

    其是一組函數(shù)脓豪,與Unix I/O結(jié)合起來巷帝,用以創(chuàng)建網(wǎng)絡(luò)應(yīng)用。

    套接字地址結(jié)構(gòu)

    ①從內(nèi)核角度看扫夜,套接字是通信的一個端點(diǎn)楞泼。

    ②從linux程序看,套接字是一個有相應(yīng)描述符的打開文件笤闯。

    因特網(wǎng)的套接字地址存放在一個結(jié)構(gòu)體中:sockaddr_in (16字節(jié))

    /* IP socket addr structure */
    struct sockaddr_in{
      uint16_t  sin_family; /*socket family(always AF_INET)*/
      uint16_t  sin_port;   /*port number in network byte order*/
      struct in_addr  sin_addr;/*IP address in network byte order*/
      unsigned char   sin_zeor[8];/*pad to sizeof(struct sockaddr)*/
    };
    
    /*generic socket addr structure(for connect,bind,accept)*/
    struct sockaddr{
      uint16_t  sa_family;  /*protocol family*/
      char      sa_data[14];/*address data*/
    };
    

實(shí)際客戶端-服務(wù)器的訪問流程如下圖:


基于套接字接口的網(wǎng)絡(luò)應(yīng)用
  • 相關(guān)函數(shù)

    • socket函數(shù)

      客戶端和服務(wù)器使用socket函數(shù)來創(chuàng)建一個套接字描述符(socket descriptor)

      客戶端和服務(wù)器都首先要用這個函數(shù)堕阔。

      #include<sys/types.h>
      #include<sys/socket.h>
      
      int socket(int domain,int type,int protocol);
                          //成功返回非負(fù)數(shù)描述符,出錯返回-1颗味;
      /* 如:clientFd = socket(AF_INET, SOCK_STREAM超陆,0);AF_INET:指明32位IP地址。SOCK_STREAM:這個套接字是連接的一個端點(diǎn)浦马。*/ 
      

      此時僅是部分打開时呀,并不能進(jìn)行讀寫,根據(jù)客戶端和服務(wù)器使用不同的方式完全打開晶默。

      這幾個函數(shù)最好用getaddrinfo函數(shù)來賦予參數(shù)谨娜。

    • connect函數(shù)

      客戶端用來與套接字地址為addr 的服務(wù)器建立網(wǎng)絡(luò)連接。

      #incldue<sys/sokcet.h>
      
      int connect(int clientfd, const struct sockaddr  *addr, socklen_t addrlen);
                      //成功返回0磺陡,出錯返回-1. 描述符保存在clientfd中趴梢。
                  //addrlen=sizeof(sockaddr_in)
      

      當(dāng)成功時,clientfd就可以讀寫了币他。此時套接字對為:

      (x:y , addr.sin_addr : addr.sin_port)

      x:客戶端IP坞靶。y:客戶端臨時端口。其唯一確定了客戶端主機(jī)的某個進(jìn)程圆丹。

    • bind函數(shù)

      socket滩愁、connect函數(shù):客戶端用來與服務(wù)器建立連接。(依次)

      socket辫封、bind硝枉、listen廉丽、accpet:服務(wù)器用來與客戶端建立連接。(依次)

      bind函數(shù)將一個套接字地址和一個套接字描述符綁定起來(如socket剛剛建立的)妻味。

      #include<sys/socket.h>
      
      int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
              //成功范圍0正压,出錯-1.
      
    • listen函數(shù)

      listen函數(shù)將一個主動套接字描述符(如bind轉(zhuǎn)化后的sockfd)轉(zhuǎn)化為監(jiān)聽套接字(listening socket),其可以接收客戶端的連接請求责球。

      說明:無論客戶段服務(wù)器焦履,內(nèi)核默認(rèn)套接字為主動套接字。所以服務(wù)器要將其轉(zhuǎn)換為監(jiān)聽套接字雏逾,說明自己是服務(wù)器端嘉裤。

      #include<sys/socket.h>
    
      int listen(int sockfd, int backlog);
                      //backlog的確切含義要求對TCP\IP協(xié)議有理解。CSAPP將其設(shè)置為較                    //大的值如:1024
    
    • accept函數(shù)

      服務(wù)器通過調(diào)用accept函數(shù)來等待來自客戶端的連接請求(connect)

      #include<sys/socket.h>
    
      int accept(int listenfd, struct sockaddr *addr, int *addrlen);
                      //成功返回已連接描述符栖博,出錯返回-1
                      //結(jié)構(gòu) addr用來安置客戶端過來的套接字地址(在結(jié)構(gòu)中一一替換)
    

會返回一個已連接描述符屑宠,用這個描述符,可以與客戶端進(jìn)行Unix I/O讀寫仇让。

注意:監(jiān)聽描述符和已連接描述符都會存在于描述符列表中典奉。

實(shí)際步驟:

①服務(wù)器調(diào)用accept,等待連接請求到達(dá)監(jiān)聽描述符丧叽。(假設(shè)=3)

②客戶端調(diào)用connect函數(shù)卫玖,請求一個連接。

③accept函數(shù)打開一個新的已連接描述符(connect descriptor)connfd(假設(shè)=4)踊淳,在clientfd和connfd之間建立連接假瞬,并隨后返回connfd給應(yīng)用程序。

客戶端也從connect返回迂尝,然后笨触,客戶端和服務(wù)器都可以通過讀寫clientfd和connfd來傳送數(shù)據(jù)。


說明:監(jiān)聽描述符是存在于服務(wù)器的生命周期內(nèi)雹舀,只會創(chuàng)建一次。而connfd則是客戶端和服務(wù)器已經(jīng)建立起來的一個端點(diǎn)粗俱。服務(wù)器每次接受連接請求都會創(chuàng)建一次说榆,其只存在于服務(wù)器為一個客戶端服務(wù)的過程中。

ps:有利于并發(fā)編程寸认。

主機(jī)和服務(wù)的轉(zhuǎn)換

  • getaddrinfo函數(shù)

    用處:主機(jī)IP地址和服務(wù)(或端口)→ 套接字地址

    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netdb.h>
    
    int getaddrinfo(const char *host, const char *service, const struct addrinfo *hints, struct addrinfo **result);
                      //成功返回0签财,錯誤返回非0的錯誤代碼,其可轉(zhuǎn)化為字符串偏塞。
                      
    void freeaddrinfo(struct addrinfo *result);
    
    const char *gai_strerror(int error);    //將錯誤代碼翻譯成字符串唱蒸。
    

    //hints是一個addrinfo結(jié)構(gòu),提供對于返回的套接字地址列表的更好的控制灸叼。只能設(shè)置下列字段:ai_family , si_socktype , ai_protocol , ai_flasg神汹。結(jié)構(gòu)中其他字段為0(NULL).

    struct addrinfo{
      int              ai_flags;
      int              ai_family;
      int              ai_socktype;
      int              ai_protocol;
      char            *ai_cannoname;
      size_t           ai_addrlen;
        struct sockaddr *ai_addr;
        struct addrinfo *ai_next;
    }
    
  • getnameinfo函數(shù)

    用處:套接字地址結(jié)構(gòu) → 主機(jī)IP地址和服務(wù)名字符串

    #include<sys/socket.h>
    #include<netdb.h>
    
    int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                  char *host, size_t hostlen,
                  char *service, size_t servlen, int flags);
              //成功返回0庆捺,錯誤返回非零錯誤代碼。
              //flags 位掩碼屁魏。
    

    getnameinfo函數(shù)將套接字地址結(jié)構(gòu)sa滔以,轉(zhuǎn)換成對應(yīng)的主機(jī)和服務(wù)名字符串,將他們復(fù)制到host和service緩沖區(qū)氓拼。

    如果返回非零你画,可以用gai_strerror(int errorcode);轉(zhuǎn)化為字符串桃漾。

以上兩個函數(shù)坏匪,如果主機(jī)名和服務(wù)名可以空白一個(NULL代替)。不能兩個都NULL撬统。

實(shí)驗(yàn)代碼在CSAPP p659适滓,或者我的linux 主機(jī)上的網(wǎng)絡(luò)編程。

  • 小結(jié):兩個關(guān)于套接字地址的結(jié)構(gòu)體:

    sockaddr:包含套接字的IP地址宪摧、端口地址粒竖、協(xié)議類型。

    addrinfo:對sockaddr結(jié)構(gòu)體的再包裝几于,附加了一些額外信息蕊苗。

用包裝過的函數(shù)創(chuàng)建連接

說明:將上述的客戶端和服務(wù)器中建立連接的函數(shù),包裝起來成為一個簡潔實(shí)用的函數(shù)沿彭。

  • open_clientfd函數(shù)

    客戶端調(diào)用此函數(shù)朽砰,建立與服務(wù)器的連接,其返回一個打開的套接字描述符喉刘。

    服務(wù)器運(yùn)行在hostname主機(jī)上的瞧柔,并監(jiān)聽了port端口。

#include<sys/socket.h>
#include<netdb.h>
#include<sys/types.h>
#include<stdio.h>

int open_clientfd(char *hostname, char *port)   //針對客戶端睦裳。
{
    int clientfd;
    struct addrinfo  hints, *listp, *p;
    
    /* get alist of server addresses */
    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_socktype = SOCK_STREAM; /*open a connection*/
    hints.ai_flags = AI_NUMERICSERV; /*using a numeric(數(shù)字) port argument*/
    hints.ai_flags |= AI_ADDRCONFIG; /*recommended for connections*/
    getaddrinfo(hostname, port, &hints, &listp);
    
    /*walk(traverl) the list for one that we can successfully connect to */
    for(p = listp; p ; p = p->ai_next ){
        
        /*create a socket descriptor */
        if((clientfd = socket(p->ai_family,p->ai_socktype,p->ai_protocol))<0)
            continue;  /*socket failed, try the next one */
        
        /*connect to the server */
        if(connect(clientfd,p->ai_addr,p->ai_addrlen)!=-1)
            break;          /*success*/
        close(clientfd);    /*connect failed, try another*/
    }
    
    /* clean up */
    freeaddrinfo(listp);
    if(!p)  return -1;   /* all connects failed */
    else    return clientfd;
}

注意:代碼具有協(xié)議無關(guān)性造锅。因?yàn)閟ocket和connect的參數(shù)都是getaddrinfo自動生成的。

  • open_listenfd

    服務(wù)器調(diào)用此函數(shù)廉邑,打開并返回一個監(jiān)聽描述符哥蔚,準(zhǔn)備好在端口port接收請求。

    #include<sys/socket.h>
    #include<netdb.h>
    #include<sys/types.h>
    #include<stdio.h>
    
    int open_listenfd(char *port)
    {
        struct addrinfo hints, *listp, *p;
        int listenfd, optval=1;
        
        /* 得到一張服務(wù)地址表 */
        memset(&hints,0 , sizeof(struct addrinfo));
        hints.ai_socktype = SOCK_STREAM;             /*類型為接收連接*/
        hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;   /*針對任何ip地址*/
        hints.ai_flags |= AI_NUMRICSERV;                  /*使用端口數(shù)字*/
        getaddrinfo(NULL, port, &hints, &listp);
        
        /* 遍歷地址表蛛蒙,找到一個可以用來綁定的 */
        for(p = listp ; p ; p = p.ai_next){
            /* 增加一個套接字描述符 */
            if((listenfd = socket(p->ai_family,p->ai_socktype,p->ai_protocol))<0)       continue;   /* 套接字不可用糙箍,試下一個 */
            
            /* 為bind中,消除“地址早已被使用”的錯誤可能 */
            setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, 
                       (const void*)&optval, sizeof(int));
            
            /* 綁定描述符和套接字地址 */
            if(bind(listenfd, p->ai_addr, p->ai_addrlen) == 0)
                break;  /*成功*/
            close(listenfd);  /*綁定失敗牵祟,關(guān)閉描述符深夯,試下一個。*/
        }
        
        /* 釋放 */
        freeaddrinfo(listp);
        if(!p) return -1;   /*沒有地址可用*/
        
        /* 使一個監(jiān)聽套接字诺苹,準(zhǔn)備好去接收一個連接請求 */
        if(listen(listenfd, LISTENQ)<0){
            close(listenfd);
            return -1;
        }
        return listenfd;
    }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咕晋,一起剝皮案震驚了整個濱河市雹拄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌捡需,老刑警劉巖办桨,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異站辉,居然都是意外死亡呢撞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門饰剥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來殊霞,“玉大人,你說我怎么就攤上這事汰蓉”炼祝” “怎么了?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵顾孽,是天一觀的道長祝钢。 經(jīng)常有香客問我,道長若厚,這世上最難降的妖魔是什么拦英? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮测秸,結(jié)果婚禮上疤估,老公的妹妹穿的比我還像新娘。我一直安慰自己霎冯,他們只是感情好铃拇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著沈撞,像睡著了一般慷荔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缠俺,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天拧廊,我揣著相機(jī)與錄音,去河邊找鬼晋修。 笑死,一個胖子當(dāng)著我的面吹牛凰盔,可吹牛的內(nèi)容都是我干的墓卦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼户敬,長吁一口氣:“原來是場噩夢啊……” “哼落剪!你這毒婦竟也來了睁本?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤忠怖,失蹤者是張志新(化名)和其女友劉穎呢堰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凡泣,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡枉疼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鞋拟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骂维。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖贺纲,靈堂內(nèi)的尸體忽然破棺而出航闺,到底是詐尸還是另有隱情,我是刑警寧澤猴誊,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布潦刃,位于F島的核電站,受9級特大地震影響懈叹,放射性物質(zhì)發(fā)生泄漏乖杠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一项阴、第九天 我趴在偏房一處隱蔽的房頂上張望滑黔。 院中可真熱鬧,春花似錦环揽、人聲如沸略荡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汛兜。三九已至,卻和暖如春通今,著一層夾襖步出監(jiān)牢的瞬間粥谬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工辫塌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漏策,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓臼氨,卻偏偏與公主長得像掺喻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

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