Linux系統(tǒng)編程2:管道

圖片來自網(wǎng)絡(luò)

1. 簡(jiǎn)介

  • 查看管道命令:man 7 pipe

分類

  • 匿名管道
  • FIFO管道/命名管道

2 匿名管道

2.1 單工管道

程序進(jìn)程與Shell命令行進(jìn)程單項(xiàng)通信。

① 打開管道FILE* popen (const char *command, const char *open_mode)

  • 參數(shù)
No. 參數(shù) 含義
1 command 命令行字符串
2 open_mode "r"只讀"w"只寫
  • 返回值
No. 返回值 含義
1 NULL 文件描述符
2 NULL 打開失敗

② 讀取size_t fread ( void *buffer, size_t size, size_t count, FILE *stream)

  • 參數(shù)
No. 參數(shù) 含義
1 buffer 用于接收數(shù)據(jù)的內(nèi)存地址
2 size 讀取每個(gè)數(shù)據(jù)項(xiàng)的字節(jié)數(shù)
3 count 數(shù)據(jù)項(xiàng)個(gè)數(shù)
4 stream 輸入流
  • 返回值
No. 返回值 含義
1 >count 出錯(cuò)
2 正數(shù) 真實(shí)讀取的數(shù)據(jù)項(xiàng)個(gè)數(shù)

③ 寫入size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream)

  • 參數(shù)
No. 參數(shù) 含義
1 buffer 寫入數(shù)據(jù)的內(nèi)存地址
2 size 寫入數(shù)據(jù)項(xiàng)的字節(jié)數(shù)
3 count 寫入數(shù)據(jù)項(xiàng)的個(gè)數(shù)
4 stream 目標(biāo)文件指針
  • 返回值
No. 返回值 含義
1 >count 出錯(cuò)
2 正數(shù) 真實(shí)寫入的數(shù)據(jù)項(xiàng)個(gè)數(shù)

④ 關(guān)閉管道int pclose(FILE *stream);

  • 參數(shù)
No. 參數(shù) 含義
1 stream 文件描述符
  • 返回值
No. 返回值 含義
1 -1 失敗
2 0 成功

示例

  • write
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(){
    FILE* fd = popen("wc","w");
    //FILE* fd = popen("ls -l","r");
    //char str[] = "123 456";       
    char str[] = "123 456\n";       
    size_t n = fwrite(str,sizeof(char),sizeof(str),fd);
    if(n > sizeof(str)){
        fprintf(stderr,"FILE:%d,LINE:%d-fwrite error",__FILE__,__LINE__);
        exit(EXIT_FAILURE);
    }
    pclose(fd);
}
  • read
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(){
    FILE* fd = popen("ps -ef","r");
    //FILE* fd = popen("ls -l","r");
         
    char buf[BUFSIZ];
    size_t count = 0;
    printf("read data:\n");
    do{
        memset(buf,'\0',BUFSIZ);
        size_t n = fread(buf,sizeof(char),BUFSIZ-1,fd);
        if( n > BUFSIZ - 1 ){
            perror("fread error");
            exit(EXIT_FAILURE);
        }
        count += n;
        printf("\n%d:\n%s",n,buf);
    }while(!feof(fd));
    printf("total size:%ld\n",count);
    pclose(fd);
}

本質(zhì)

  • 啟動(dòng)shell和命令兩個(gè)進(jìn)程句柠,從命令進(jìn)程中讀/寫文件流袁勺。
  • 解決exec和system無法返回輸出數(shù)據(jù)問題

特點(diǎn)

  • 方便使用系統(tǒng)自帶功能,并且可以執(zhí)行比較復(fù)雜Shell
  • 默認(rèn)啟動(dòng)兩個(gè)進(jìn)程,效率較低。
操作 管道 文件
打開 popen() fopen()
關(guān)閉 pclose() fclose()

2.2 半雙工管道

① 創(chuàng)建管道int pipe(int filedes[2])

  • 參數(shù)
No. 參數(shù) 含義
1 filedes[0]
2 filedes[1]
  • 返回值
No. 返回值 含義
1 -1 失敗
2 0 成功

② 讀取ssize_t write(int fd, const void *buf, size_t nbyte)

  • 參數(shù)
No. 參數(shù) 含義
1 fd 文件描述符
2 buf 寫入數(shù)據(jù)的內(nèi)存單元
3 nbyte 寫入文件指定的字節(jié)數(shù)
  • 返回值
No. 返回值 含義
1 -1 出錯(cuò)
2 正數(shù) 寫入的字節(jié)數(shù)

③ 寫入ssize_t read(int fd, void *buf, size_t count)

  • 參數(shù)
No. 參數(shù) 含義
1 fd 文件描述符
2 buf 讀取數(shù)據(jù)的內(nèi)存單元
  • 返回值
No. 返回值 含義
1 -1 出錯(cuò)
2 0 無數(shù)據(jù)
3 正數(shù) 讀取的字節(jié)數(shù)

④ 控制int fcntl(int fd, int cmd, long arg)

如果管道是空的,read()默認(rèn)是阻塞

  • 參數(shù)
No. 參數(shù) 含義
1 fd 文件描述符
2 cmd F_GETFL:獲取文件描述符狀態(tài);F_SETFL:設(shè)置文件描述符狀態(tài);
3 arg O_NONBLOCK:非阻塞;O_BLOCK:阻塞

把文件描述符改為非阻塞的fcntl(filedes,F_SETFL,O_NONBLOCK);

⑤ 關(guān)閉管道close(filedes)

示例

  • 單進(jìn)程讀寫管道
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(){
    int fd[2];
    pipe(fd);
    char in[] = "Hello pipe";
    write(fd[1],in,sizeof(in));
    printf("write:%s\n",in);
 
    char out[sizeof(in)]={0};
    ssize_t n = read(fd[0],out,sizeof(out));
    if(-1 == n){
        perror("read error");
        return -1;
    }
    printf("read:%s\n",out);
 
    close(fd[0]);
    close(fd[1]);
}
  • 兩進(jìn)程讀寫
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(){
    int fd[2];
    pipe(fd);
    if(!fork()){// child
        char in[] = "Hello pipe";
        write(fd[1],in,sizeof(in));
        printf("child %d write:%s\n",getpid(),in);
    }else{// parent
        char out[BUFSIZ]={0};
        ssize_t n = read(fd[0],out,sizeof(out));
        if(-1 == n){
            perror("read error");
            return -1;
        }
        printf("parent %d read:%s\n",getpid(),out);
    }
    close(fd[0]);
    close(fd[1]);
}
  • 兩進(jìn)程先讀后寫
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(){
    int fd[2];
    pipe(fd);
    if(!fork()){// child
        char in[] = "Hello pipe";
        sleep(3);
        write(fd[1],in,sizeof(in));
        printf("child %d write:%s\n",getpid(),in);
    }else{// parent
        char out[BUFSIZ]={0};
        ssize_t n = read(fd[0],out,sizeof(out));
        if(-1 == n){
            perror("read error");
            return -1;
        }
        printf("parent %d read:%s\n",getpid(),out);
    }
    close(fd[0]);
    close(fd[1]);
}
  • 兩進(jìn)程先讀后寫(非阻塞)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
 
int main(){
    int fd[2];
    pipe(fd);
    if(!fork()){// child
        char in[] = "Hello pipe";
        sleep(3);
        write(fd[1],in,sizeof(in));
        printf("child %d write:%s\n",getpid(),in);
    }else{// parent
        fcntl(fd[0],F_SETFL,O_NONBLOCK);
        char out[BUFSIZ]={0};
        ssize_t n = read(fd[0],out,sizeof(out));
        if(-1 == n){
            perror("read error");
            return -1;
        }
        printf("parent %d read:%s\n",getpid(),out);
    }
    close(fd[0]);
    close(fd[1]);
}
  • 更加規(guī)范的寫法(關(guān)閉不需要的管道)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
 
int main(){
    int fd[2];
    pipe(fd);
    if(!fork()){// child
        close(fd[0]);
        char in[] = "Hello pipe";
        sleep(3);
        write(fd[1],in,sizeof(in));
        printf("child %d write:%s\n",getpid(),in);
        close(fd[1]);
    }else{// parent
        close(fd[1]);
        fcntl(fd[0],F_SETFL,O_NONBLOCK);
        char out[BUFSIZ]={0};
        ssize_t n = read(fd[0],out,sizeof(out));
        if(-1 == n){
            perror("read error");
            return -1;
        }
        printf("parent %d read:%s\n",getpid(),out);
        close(fd[0]);
    }
}

2.3 FIFO管道/命名管道

① 創(chuàng)建命名管道int mkfifo(pathname,mode)

  • 參數(shù)
No. 參數(shù) 含義
1 pathname 文件路徑妹卿,文件必須不存在
2 mode 模式
  • 返回值
No. 返回值 含義
1 0 成功
2 非零 失敗
  • 示例
#include <stdio.h>
#include <unistd.h>

int main(){
    if(-1 == mkfifo("/tmp/test",0644)){
        perror("mkfifo error");
        return 1;
    }
}

注意:

  1. 管道文件通常在/tmp目錄下創(chuàng)建。
  2. 管道文件大小通常是0

② 打開FIFO文件int open(const char *path, int mode)

  • 參數(shù)
No. 參數(shù) 含義
1 pathname 文件路徑
2 mode 模式
  • 模式
No. 模式 含義
1 O_RDONLY 阻塞只讀
2 O_RDONLY | O_NONBLOCK 非阻塞只讀
3 O_WRONLY 阻塞只寫
4 O_WRONLY | O_NONBLOCK 非阻塞只寫
  • 返回值
No. 返回值 含義
1 -1 失敗
2 其他 文件描述符

示例

  1. 阻塞讀
#include <iostream>
#include <unistd.h>
#include <fcntl.h> // open() O_RDONLY
using namespace std;
#define BUFSIZE 258

int main(){
    // 打開命名管道
    int fd = open("/tmp/fifo",O_RDONLY);
    if(-1 == fd){
        perror("open error");
        return EXIT_FAILURE;
    }else{
        cout << "filo open ok" << endl;
    }
    
    // 讀取字符串
    char buffer[BUFSIZE] = {0};
    read(fd,buffer,BUFSIZE);
    
    // 打印讀取的字符串
    cout << buffer << endl;
    
    // 關(guān)閉管道
    close(fd);
    return EXIT_SUCCESS;
}
  • 堵塞寫
#include <iostream>
#include <fcntl.h> // open() O_WRONLY
#include <unistd.h>
using namespace std;

int main(){
    // 打開命名管道
    int fd = open("/tmp/fifo",O_WRONLY);
    if(-1 == fd){
        perror("open error");
        return EXIT_FAILURE;
    }else{
        cout << "filo open ok" << endl;
    }
    
    // 讀取字符串
    string str;
    getline(cin,str);
    
    // 寫入管道
    write(fd,str.c_str(),str.size()+1);
    
    // 關(guān)閉管道
    close(fd);
    return EXIT_SUCCESS;
}
  • 寫非阻塞
    說明:
    1. 只需要在open()添加O_NONBLOCK
    2. open()非阻塞纽帖,讀open()阻塞的情況宠漩。讀open()需要先執(zhí)行举反,否則懊直,寫open()會(huì)出現(xiàn)No such device or address
#include <iostream>
#include <fcntl.h> // open() O_WRONLY O_NONBLOCK
#include <unistd.h>
using namespace std;

int main(){
    // 打開命名管道
    int fd = open("/tmp/fifo",O_WRONLY|O_NONBLOCK);
    if(-1 == fd){
        perror("open error");
        return EXIT_FAILURE;
    }else{
        cout << "filo open ok" << endl;
    }
    
    // 讀取字符串
    string str;
    getline(cin,str);
    
    // 寫入管道
    write(fd,str.c_str(),str.size()+1);
    
    // 關(guān)閉管道
    close(fd);
    return EXIT_SUCCESS;
}
  • 讀非阻塞
    說明:
    1. 只需要在open()添加O_NONBLOCK火鼻。
    2. open()阻塞室囊,讀open()非阻塞的情況。讀read()需要處理寫open()未執(zhí)行(read()返回0)和讀不到數(shù)據(jù)(寫open()打開但是沒有寫數(shù)據(jù)魁索,read()返回-1)的情況融撞。
#include <iostream>
#include <unistd.h>
#include <fcntl.h> // open() O_RDONLY O_NONBLOCK
using namespace std;
#define BUFSIZE 258

int main(){
    // 打開命名管道
    int fd = open("/tmp/fifo",O_RDONLY|O_NONBLOCK);
    if(-1 == fd){
        perror("open error");
        return EXIT_FAILURE;
    }else{
        cout << "filo open ok" << endl;
    }
    
    // 讀取字符串
    char buffer[BUFSIZE] = {0};
    int n = -1;
    while(n<=0){
        n=read(fd,buffer,BUFSIZE);
    }
    // 打印讀取的字符串
    cout << buffer << endl;
    
    // 關(guān)閉管道
    close(fd);
    return EXIT_SUCCESS;
}

特點(diǎn)

  • 可以是非親緣進(jìn)程之間
  • FIFO首先會(huì)阻塞在open(),等待讀寫文件的文件描述符都打開粗蔚。接著阻塞在read()/write()操作尝偎,讀寫操作需要同時(shí)執(zhí)行。

案例

  • FIFO工具箱

3. 通信分類

只寫單工
只讀單工
半雙工
全雙工
No. 類型 創(chuàng)建/打開 關(guān)閉
1 單工 popen() pclose fread() fwrite()
2 半雙工 pipe()/open() close() read() write()
3 FIFO半雙工 mkfifo()/open close()/unlink() read() write()
4 全雙工 socketpair() close() read() write()

3.1 單進(jìn)程管道

單進(jìn)程管道

管道通常用于進(jìn)程間通信

3.2 父子進(jìn)程單向管道

3.3.1 概念圖解

父子進(jìn)程管道
父進(jìn)程關(guān)閉fd[0] 子進(jìn)程關(guān)閉fd[1]
父子進(jìn)程單向管道

3.3.2 原理圖解

3.3 父子進(jìn)程雙向管道

父子進(jìn)程雙向管道

4. 文件描述符

4.1 Linux文件讀寫與標(biāo)準(zhǔn)C的文件讀寫

文件描述符

文件描述符 文件流
數(shù)據(jù) int整數(shù) FILE指針
標(biāo)準(zhǔn) POSIX ANSI C
打開 open fopen
關(guān)閉 close fclose
read fread
write fwrite
定位 lseek fseek
  • 文件流是文件描述符之上的封裝鹏控。文件流通過增加緩沖區(qū)減少讀寫系統(tǒng)調(diào)用次數(shù)來提高讀寫效率致扯。在進(jìn)程的用戶空間封裝的FILE結(jié)構(gòu),以提高可移植性和效率当辐。

4.2 文件描述符原理

Linux內(nèi)核使用三個(gè)關(guān)聯(lián)的數(shù)據(jù)結(jié)構(gòu)抖僵,表示打開的文件。

  • 打開不同的文件


  • 打開相同的文件


  • 父子進(jìn)程共享文件


4.3 命令lsof

lsof(list open files):列出當(dāng)前系統(tǒng)打開文件

  • 列名含義
No. 列名 含義
1 COMMAND 進(jìn)程的名稱
2 PID 進(jìn)程標(biāo)識(shí)符
3 USER 進(jìn)程所有者
4 FD 文件描述符缘揪,應(yīng)用程序通過文件描述符識(shí)別該文件耍群。如cwd、txt等
5 TYPE 文件類型找筝,如PIPE蹈垢、DIRREG
6 DEVICE 指定磁盤的名稱
7 SIZE 文件的大小
8 NODE 索引節(jié)點(diǎn)(文件在磁盤上的標(biāo)識(shí))
9 NAME 打開文件的確切名稱
  • 常用方法
No. 命令 作用
1 lsof 文件名 查看文件打開信息
2 lsof -d 文件描述符 查看文件描述符信息
3 lsof -p PID 查看進(jìn)程PID打開的文件信息

4.3 文件描述符復(fù)制

分類 文件描述符 文件號(hào)
標(biāo)準(zhǔn)輸入 STDIN_FILENO 0
標(biāo)準(zhǔn)輸出 STDOUT_FILENO 1
標(biāo)準(zhǔn)出錯(cuò)信息 STDERR_FILENO 2

內(nèi)核為每個(gè)進(jìn)程創(chuàng)建的文件描述符袖裕。

  • 示例
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(){
    char str[1024];
    scanf("%s",str);
    printf("%s\n",str);

    read(STDIN_FILENO,str,sizeof(str));
    write(STDOUT_FILENO,str,strlen(str));
}

① 函數(shù)int dup(int oldfd)

  • 參數(shù)
No. 參數(shù) 含義
1 oldfd 舊文件描述符
  • 返回值
No. 返回值 含義
1 -1 失敗
2 其他 新文件描述符

② 函數(shù)int dup2(int oldfd, int newfd)

  • 參數(shù)
No. 參數(shù) 含義
1 oldfd 舊文件描述符
2 newfd 新文件描述符
  • 返回值
No. 返回值 含義
1 -1 失敗
2 其他 最小及尚未使用的文件描述符

示例

  • 復(fù)制標(biāo)準(zhǔn)輸出
    新文件描述符與舊文件描述符不同耘婚,但是具備舊文件描述符功能
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
int main(){
    int fd = dup(STDOUT_FILENO);
    fprintf(fdopen(fd,"w"),"%d printf:Hello dup\n",fd);
}
  • 復(fù)制文件描述符
    新文件描述符與舊文件描述符不同,但是具備舊文件描述符功能
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)
 
int main(){
    int fd = open("./test",O_CREAT|O_RDWR,FILE_MODE); 
    char str[]="Hello dup\n";
    write(fd,str,sizeof(str));
    int cp_fd = dup(fd);
    printf("copy %d to %d",fd,cp_fd);
    write(cp_fd,str,sizeof(str));
    //fprintf(fdopen(fd,"w"),"%d printf:Hello dup\n",fd);
    close(fd);
}
  • 把文件描述符重定向(復(fù)制)到標(biāo)準(zhǔn)輸出
    printf()直接輸出到文件中陆赋,不再輸出到終端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
 
#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)
 
int main(){
    int fd = open("./test",O_CREAT|O_RDWR,FILE_MODE); 
    char str[]="Hello dup\n";
    dup2(fd,STDOUT_FILENO);
    printf("%d printf:Hello dup\n",fd);
}
  • 把文件描述符重定向(復(fù)制)到標(biāo)準(zhǔn)輸出沐祷,并且輸出后還原
    注意把標(biāo)準(zhǔn)輸出流從文件重定向(復(fù)制)回終端,需要清除緩沖區(qū)攒岛。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)
int main(){
    int save_fd = dup(STDOUT_FILENO);
    int fd = open("./test",O_CREAT|O_RDWR,FILE_MODE); 
    if(-1 == dup2(fd,STDOUT_FILENO)){
        perror("dup2 error0");
        return 1;
    }
    close(fd);
    printf("%d printf:Hello dup\n",fd);
    fflush(stdout);// 一定要清除緩沖區(qū)赖临,否則會(huì)輸出到終端
    if(-1 == dup2(save_fd,STDOUT_FILENO)){
        perror("dup2 error");
        return 1;
    }
    close(save_fd);
    printf("%d printf:this is save\n",save_fd);
}

特點(diǎn)

必須是親緣進(jìn)程之間

dup()/dup2()原理圖

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市灾锯,隨后出現(xiàn)的幾起案子兢榨,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吵聪,死亡現(xiàn)場(chǎng)離奇詭異凌那,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吟逝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門帽蝶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人块攒,你說我怎么就攤上這事励稳。” “怎么了囱井?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵驹尼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我庞呕,道長(zhǎng)新翎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任住练,我火速辦了婚禮地啰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘澎羞。我一直安慰自己髓绽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布妆绞。 她就那樣靜靜地躺著顺呕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪括饶。 梳的紋絲不亂的頭發(fā)上株茶,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音图焰,去河邊找鬼启盛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛技羔,可吹牛的內(nèi)容都是我干的僵闯。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼藤滥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鳖粟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拙绊,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤向图,失蹤者是張志新(化名)和其女友劉穎泳秀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榄攀,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗜傅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了檩赢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吕嘀。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖漠畜,靈堂內(nèi)的尸體忽然破棺而出币他,到底是詐尸還是另有隱情坞靶,我是刑警寧澤憔狞,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站彰阴,受9級(jí)特大地震影響瘾敢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尿这,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一簇抵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧射众,春花似錦碟摆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至罗洗,卻和暖如春愉舔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背伙菜。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工轩缤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贩绕。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓火的,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親淑倾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子馏鹤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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