untiy 使用UDP發(fā)送圖片,并將接收到的圖片保存到本地

前言:

UDP客戶(hù)端作為圖片發(fā)送方奖唯,UDP服務(wù)端作為圖片接收方惨缆。

實(shí)現(xiàn)功能:

在發(fā)送方鼠標(biāo)左鍵點(diǎn)擊game視圖,將本地圖片發(fā)送到接收方,接收方將收到的圖片保存到本地坯墨,并將接收到的圖片在UI上展示幾秒鐘寂汇。

發(fā)送方腳本掛載方式:

udpclient.png

接收方腳本掛載方式:

udpserver.png

客戶(hù)端代碼:

NewUDPClient:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

public class NewUDPClient : MonoBehaviour {

    public static NewUDPClient instance;
    //服務(wù)端的IP
    string UDPClientIP;
    //目標(biāo)socket 
    Socket socket;
    //服務(wù)端 
    EndPoint serverEnd;
    //服務(wù)端端口 
    IPEndPoint ipEnd;
    //接收的字符串 
    string recvStr;
    //接收的數(shù)據(jù),必須為字節(jié) 
    byte[] recvData;
    //發(fā)送的數(shù)據(jù)捣染,必須為字節(jié) 
    byte[] sendData;
    //接收的數(shù)據(jù)長(zhǎng)度 
    int recvLen = 0;
    //連接線(xiàn)程
    Thread connectThread;

    bool isClientActive = false;

    //連接服務(wù)器時(shí)發(fā)送的vector3類(lèi)型
    Vector3 startVec = Vector3.zero;

    bool isStartHeart = false;


    int port;

    //判斷是否讓客戶(hù)端重新發(fā)送數(shù)據(jù)包
    bool isReSend = false;
    string reSendStrIndex;

    public delegate void ReSendIndexDeledate(string str);
    public event ReSendIndexDeledate ReSendIndexEvent;


    private void Awake()
    {
        instance = this;
    }

    void Start()
    {
        UDPClientIP = "127.0.0.1";//服務(wù)端的IP.自己更改
        port = 9000;
        UDPClientIP = UDPClientIP.Trim();
        isClientActive = true;
        InitSocket(); //在這里初始化
    }

    private void Update()
    {
        if (isStartHeart)
        {
            HeartSend();
        }
        //檢測(cè)心跳與心跳反饋的間隔時(shí)間健无,
        timerInterval += Time.deltaTime;

        if (timerInterval > 6f)
        {
            print("連接異常");
            timerInterval = 0f;
        }


        if (isReSend)
        {
            print(111);
            if (ReSendIndexEvent!=null)
            {
                ReSendIndexEvent(reSendStrIndex);
                reSendStrIndex = null;
                isReSend = false;
            }
        }
    }

    //初始化 
    void InitSocket()
    {
        //定義連接的服務(wù)器ip和端口,可以是本機(jī)ip液斜,局域網(wǎng)累贤,互聯(lián)網(wǎng) 
        ipEnd = new IPEndPoint(IPAddress.Parse(UDPClientIP), port);
        //定義套接字類(lèi)型,在主線(xiàn)程中定義 
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        //socket.Bind(ipEnd);
        //定義服務(wù)端 
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        serverEnd = (EndPoint)sender;
        print("local:等待連接");
        isStartHeart = true;
        //開(kāi)始心跳監(jiān)聽(tīng)
        //客戶(hù)端發(fā)送心跳消息后,計(jì)時(shí)器開(kāi)始計(jì)時(shí)少漆,判斷3秒內(nèi)是否能收到服務(wù)端的反饋
        HeartSend();
        //開(kāi)啟一個(gè)線(xiàn)程連接臼膏,否則主線(xiàn)程卡死 
        connectThread = new Thread(new ThreadStart(SocketReceive));
        connectThread.Start();
    }

    //發(fā)送字符串
    public void SocketSend(string sendStr)
    {
        //清空發(fā)送緩存 
        sendData = new byte[1500];
        //數(shù)據(jù)類(lèi)型轉(zhuǎn)換 
        sendData = Encoding.UTF8.GetBytes(sendStr);
        //發(fā)送給指定服務(wù)端
        socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
    }

    //發(fā)送消息頻率
    float timerRate = 5;
    //接收服務(wù)端心跳反饋的時(shí)間間隔
    float timerInterval = 0f;

    byte[] heartSendData = new byte[1024];

    /// <summary>
    /// 心跳
    /// </summary>
    void HeartSend()
    {
        timerRate += Time.deltaTime;
        if (timerRate > 5f)
        {
            try
            {
                SocketSend("alive");
            }
            catch 
            {
            }
            timerRate = 0f;
        }
    }

    //客戶(hù)端接收服務(wù)器消息
    void SocketReceive()
    {
        //進(jìn)入接收循環(huán) 
        while (isClientActive)
        {
            //對(duì)data清零 
            recvData = new byte[20000];
            try
            {
                //獲取服務(wù)端端數(shù)據(jù)
                recvLen = socket.ReceiveFrom(recvData, ref serverEnd);
                if (isClientActive == false)
                {
                    break;
                }
            }
            catch
            {

            }
            //輸出接收到的數(shù)據(jù) 
            if (recvLen > 0)
            {
                //接收到的信息
                recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen);
            }
            print("server:" + recvStr);

            //心跳回饋
            if (recvStr == "keeping")
            {
                // 當(dāng)服務(wù)端收到客戶(hù)端發(fā)送的alive消息時(shí)
                print("連接正常");
                timerInterval = 0;
            }
            else if(recvStr!=null)
            {
                reSendStrIndex = recvStr;
                isReSend = true;
            }
        }
    }

    //連接關(guān)閉
    void SocketQuit()
    {
        //最后關(guān)閉socket
        if (socket != null)
            socket.Close();
    }
    void OnApplicationQuit()
    {
        isStartHeart = false;
        isClientActive = false;
        SocketQuit();
        Thread.Sleep(25);
    }
}

SendImageScript:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using System.Threading;
public class SendImageScript : MonoBehaviour {
    
    byte[] imagebytes;
    
    string newImageString;
    string path;

    private void Start()
    {
        NewUDPClient.instance.ReSendIndexEvent += GetReSendIndexFromUDPClient;
        path = Application.streamingAssetsPath + "/" + "222.jpg";

        FileStream files = new FileStream(path, FileMode.Open);
        imagebytes = new byte[files.Length]; files.Read(imagebytes, 0, imagebytes.Length); files.Close();
        files.Close();
        picStr = Convert.ToBase64String(imagebytes);
    }


    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
          
            StartCoroutine(SendPicture());
        }
    }

    string picStr;
    IEnumerator SendPicture() {
        UDPSplit(picStr);
        //將圖片發(fā)送給投影機(jī)
       yield return new WaitForSeconds(0.1f);

        for (int i = 0; i < num - 1000; i++)
        {
            if (UDPStringDic.TryGetValue(i, out newImageString))
            {
                NewUDPClient.instance.SocketSend(newImageString);
            }
        }

        yield return new WaitForSeconds(0.1f);
        //發(fā)送完成后發(fā)一條信息給服務(wù)端
        NewUDPClient.instance.SocketSend("done");
    }

    string[] reSendNum;
    int newindex;
    void GetReSendIndexFromUDPClient(string str)
    {
        reSendNum = str.Split('_');

        for (int i = 0; i < reSendNum.Length; i++)
        {
            if (int.TryParse(reSendNum[i], out newindex))
            {
                if (UDPStringDic.TryGetValue(newindex, out newImageString))
                {
                    NewUDPClient.instance.SocketSend(newImageString);
                }
            }
        }
        //發(fā)送完成后發(fā)一條信息給服務(wù)端
        NewUDPClient.instance.SocketSend("done");
        print("重新發(fā)送完畢");

    }



    Dictionary<int, string> UDPStringDic = new Dictionary<int, string>();
    int index = 0;
    int maxIndex = 1000;
    string newstr;
    int num;
    
    void UDPSplit(string str)
    {
        index = 0;
        maxIndex = 1000;
        int stringTag = 1000;
        UDPStringDic.Clear();
        num = (str.Length / 1000) + 1 + 1000;   //將數(shù)字變成四位數(shù)的,三個(gè)字節(jié)
                                                //  print(num-1000);
        for (int i = 0; i < num - 1000; i++)
        {
            if (maxIndex > str.Length - index)
            {
                maxIndex = str.Length - index;
            }
            newstr = "1551683020" + "_" + num + "_" + stringTag + "_" + str.Substring(index, maxIndex); //包名示损,包長(zhǎng)渗磅,包的順序號(hào),包的內(nèi)容


            UDPStringDic.Add(stringTag - 1000, newstr);
            stringTag++;
            index += 1000;
        }
    }


    public static long GetTimeStamp(bool bflag = true)
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        long ret;
        if (bflag)
            ret = Convert.ToInt64(ts.TotalSeconds);
        else
            ret = Convert.ToInt64(ts.TotalMilliseconds);
        return ret;
    }

    private void OnDisable()
    {
        NewUDPClient.instance.ReSendIndexEvent -= GetReSendIndexFromUDPClient;
    }
}

服務(wù)端代碼

NewUDPServer:

using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;
using System.IO;
using UnityEngine.UI;

public class NewUDPServer : MonoBehaviour {

    public static NewUDPServer instance;
    Socket socket; //目標(biāo)socket
    EndPoint clientEnd; //客戶(hù)端
    IPEndPoint ipEnd; //偵聽(tīng)端口
    [HideInInspector]
    public string recvStr; //接收的字符串
    string sendStr; //發(fā)送的字符串
    byte[] recvData; //接收的數(shù)據(jù)检访,必須為字節(jié)
    byte[] sendData = new byte[1024]; //發(fā)送的數(shù)據(jù)始鱼,必須為字節(jié)
    int recvLen; //接收的數(shù)據(jù)長(zhǎng)度
    Thread connectThread; //連接線(xiàn)程
    [HideInInspector]
    public bool isStartSend = false;
    int port;

    bool isSendImage;
    public delegate void UDPServerDeledate(Texture2D byths);
    public event UDPServerDeledate UDPserverEvent;

    //接收到的圖片字節(jié)數(shù)組的圖片字節(jié)長(zhǎng)度
    int imageLength;

    string imageStr;

    /// <summary>
    /// 初始化
    /// </summary>
    void InitSocket()
    {
        //定義偵聽(tīng)端口,偵聽(tīng)任何IP 
        ipEnd = new IPEndPoint(IPAddress.Any, port);
        //定義套接字類(lèi)型,在主線(xiàn)程中定義 
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
        //服務(wù)端需要綁定ip 
        socket.Bind(ipEnd);
        //定義客戶(hù)端
        IPEndPoint sender = new IPEndPoint(IPAddress.Broadcast, 0);
        clientEnd = (EndPoint)sender;
        print("local:等待連接數(shù)據(jù)");
        //開(kāi)啟一個(gè)線(xiàn)程連接
        connectThread = new Thread(new ThreadStart(SocketReceive));
        connectThread.Start();
    }

    /// <summary>
    /// 服務(wù)器向客戶(hù)端發(fā)送消息
    /// </summary>
    /// <param name="sendStr"></param>
    public void SocketSend(string sendStr)
    {
        //清空發(fā)送緩存 
        sendData = new byte[20000];
        //數(shù)據(jù)類(lèi)型轉(zhuǎn)換 
        sendData = Encoding.UTF8.GetBytes(sendStr);
        //發(fā)送給指定客戶(hù)端 
        socket.SendTo(sendData, sendData.Length, SocketFlags.None, clientEnd);
    }

    bool isServerActive = false;

    /// <summary>
    /// 服務(wù)器接收來(lái)自客戶(hù)端的消息
    /// </summary>
    void SocketReceive()
    {
        //進(jìn)入接收循環(huán) 
        while (isServerActive)
        {
            //對(duì)data清零 
            recvData = new byte[1500];
            try
            {
                //獲取服務(wù)端端數(shù)據(jù)
                recvLen = socket.ReceiveFrom(recvData, ref clientEnd);
                if (isServerActive == false)
                {
                    break;
                }
            }
            catch
            {

            }

            if (recvLen > 0)
            {
                recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen);
                //輸出接收到的數(shù)據(jù) 
                // Debug.Log("Clent:__" + recvStr + "++" + recvLen);
                //客戶(hù)端心跳回饋
                if (recvStr == "alive")
                {
                    HeartCheck();
                }
                else if (recvStr == "done")
                {
                    //當(dāng)接收到的信息為done時(shí),判斷接收到的圖片包數(shù)量是否夠脆贵,不夠就發(fā)送未收到的包的標(biāo)識(shí)號(hào)医清,讓客戶(hù)端再發(fā)送一下
                    CheckPackage();

                }
                else if (recvLen > 18) //圖片包頭為29個(gè)字節(jié)
                {
                    // print("這是圖片");
                    //合并發(fā)來(lái)的圖片
                    ConmbineString(recvStr);
                }
            }
        }
    }

    //未發(fā)送包的標(biāo)識(shí)號(hào)
    string reSendPackageindex;
    /// <summary>
    /// 當(dāng)接收到客戶(hù)端發(fā)送的done消息后,判斷接收到的圖片包是否完整
    /// </summary>
    void CheckPackage()
    {
        reSendPackageindex = null;
        if (doneIndex.Count <= 0)
        {
            print("接收成功");
            for (int i = 0; i < newImageDic.Count; i++)
            {
                if (newImageDic.TryGetValue(i, out dicStr))
                {
                    newConbineStr = newConbineStr + dicStr;
                }
            }
            isSendImage = true;
            newImageCount = 0;
            newStrIndex = 0;
            isFirst = true;
            newImageDic.Clear();
            doneIndex.Clear();
        }
        else
        {
            print("接收失敗卖氨,重新請(qǐng)求");
            //判斷哪些包沒(méi)有收到
            for (int i = 0; i < doneIndex.Count; i++)
            {
                reSendPackageindex = doneIndex[i] + "_" + reSendPackageindex;
            }

            SocketSend(reSendPackageindex);
            print("請(qǐng)求發(fā)送未成功包");
        }
    }

    
    string newConbineStr;
    string newImageName;
    int newImageCount = 0;
    int newStrIndex = 0;
    string newImageMessage;
    //判斷是否是第一次接受消息
    bool isFirst = true;
    string oldImageName;
    Dictionary<int, string> newImageDic = new Dictionary<int, string>();
    List<int> doneIndex = new List<int>();

    string dicStr;
    //將分包發(fā)來(lái)的消息合成一個(gè)包
    void ConmbineString(string perStr)
    {
        //0.圖片名字(21字節(jié))--1.包的長(zhǎng)度(1000為起始點(diǎn)会烙,4字節(jié))--2.包的下標(biāo)(1000為起始點(diǎn)4個(gè)字節(jié))--3.包的內(nèi)容
        //分割字符串 "_"
        string[] strs = perStr.Split('_');
        //名字
        newImageName = strs[0];
        newImageCount = int.Parse(strs[1]) - 1000;
        newStrIndex = int.Parse(strs[2]) - 1000;
        newImageMessage = strs[3];

        if (isFirst)
        {
            oldImageName = newImageName;
            isFirst = false;
            newConbineStr = null;
            //將將要收到的包的標(biāo)識(shí)號(hào)存進(jìn)集合里邊,每接收到對(duì)應(yīng)的數(shù)據(jù)就移除該標(biāo)識(shí)號(hào)
            for (int i = 0; i < newImageCount; i++)
            {
                doneIndex.Add(i);
            }
        }
        
        if (newImageName == oldImageName)
        {
            // print(newImageCount);
            if (!newImageDic.ContainsKey(newStrIndex))
            {
                //每接收到對(duì)應(yīng)的數(shù)據(jù)就移除該標(biāo)識(shí)號(hào)
                try
                {
                    doneIndex.Remove(newStrIndex);
                }
                catch
                {
                    print("數(shù)據(jù)傳輸失敗");
                }

                newImageDic.Add(newStrIndex, newImageMessage);
            }
        }
    }

    float timerInterval = 0;
    bool isStartCheck = false;

    void HeartCheck()
    {
        isStartCheck = true;
        timerInterval = 0f;
        SocketSend("keeping");
        print("連接正常");
    }

    void Update()
    {
        timerInterval += Time.deltaTime;
        if (isStartCheck)
        {
            if (timerInterval > 6f)
            {
                print("網(wǎng)絡(luò)連接異常");
                timerInterval = 0f;
            }
        }

        if (isSendImage)
        {
            ParseBYTeArr(newConbineStr);
            newConbineStr = null;
            isSendImage = false;
        }
    }

    /// <summary>
    /// 發(fā)來(lái)的字節(jié)包括:圖片的字節(jié)長(zhǎng)度(前四個(gè)字節(jié))和圖片字節(jié)
    /// 得到發(fā)來(lái)的字節(jié)中圖片字節(jié)長(zhǎng)度和圖片字節(jié)數(shù)組
    /// </summary>
    void ParseBYTeArr(string receStr)
    {
        byte[] bytes = Convert.FromBase64String(receStr);

        string timestamp = GetTimeStamp().ToString();
        string filename = Application.streamingAssetsPath + "/Imags/"+timestamp + ".jpg";
        File.WriteAllBytes(filename, bytes);

        Texture2D tex2D = new Texture2D(100, 100);
        tex2D.LoadImage(bytes);

        if (UDPserverEvent != null)
        {
            UDPserverEvent(tex2D);
        }
    }


    //連接關(guān)閉
    void SocketQuit()
    {
        //最后關(guān)閉socket
        if (socket != null)
        {
            try
            {
                socket.Close();
            }
            catch
            {

            }
        }

        Debug.LogWarning("local:斷開(kāi)連接");
    }

    private void Awake()
    {
        instance = this;
    }

    void Start()
    {
        port = 9000;
        isServerActive = true;
        InitSocket(); //在這里初始化server
    }

    void OnDisable()
    {
        isServerActive = false;
        SocketQuit();
        Thread.Sleep(100);
    }

    public static long GetTimeStamp(bool bflag = true)
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        long ret;
        if (bflag)
            ret = Convert.ToInt64(ts.TotalSeconds);
        else
            ret = Convert.ToInt64(ts.TotalMilliseconds);
        return ret;
    }
}

LoadImageFromClient:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class LoadImageFromClient : MonoBehaviour {

    public RawImage newImage;
    public Transform showPanel;

    void Start()
    {
        NewUDPServer.instance.UDPserverEvent += ReceiveByteFromUDPServer;
    }

    /// <summary>
    /// 發(fā)來(lái)的字節(jié)包括:圖片的字節(jié)長(zhǎng)度(前四個(gè)字節(jié))和圖片字節(jié)
    /// 得到發(fā)來(lái)的字節(jié)中圖片字節(jié)長(zhǎng)度和圖片字節(jié)數(shù)組
    /// </summary>
    void ReceiveByteFromUDPServer(Texture2D newTexture)
    {
        newImage.gameObject.SetActive(true);
        newImage.texture = newTexture;
        Invoke("SetDefultImage", 5f);
    }

    void SetDefultImage() {
        newImage.texture = null;
    }

    void OnDisable()
    {
        NewUDPServer.instance.UDPserverEvent -= ReceiveByteFromUDPServer;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末筒捺,一起剝皮案震驚了整個(gè)濱河市柏腻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌系吭,老刑警劉巖五嫂,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異肯尺,居然都是意外死亡沃缘,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)蟆盹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)孩灯,“玉大人闺金,你說(shuō)我怎么就攤上這事逾滥。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵寨昙,是天一觀的道長(zhǎng)讥巡。 經(jīng)常有香客問(wèn)我,道長(zhǎng)舔哪,這世上最難降的妖魔是什么欢顷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮捉蚤,結(jié)果婚禮上抬驴,老公的妹妹穿的比我還像新娘。我一直安慰自己缆巧,他們只是感情好布持,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著陕悬,像睡著了一般题暖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捉超,一...
    開(kāi)封第一講書(shū)人閱讀 49,985評(píng)論 1 291
  • 那天胧卤,我揣著相機(jī)與錄音,去河邊找鬼拼岳。 笑死枝誊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惜纸。 我是一名探鬼主播侧啼,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼堪簿!你這毒婦竟也來(lái)了痊乾?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤椭更,失蹤者是張志新(化名)和其女友劉穎哪审,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體虑瀑,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡湿滓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了舌狗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叽奥。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖痛侍,靈堂內(nèi)的尸體忽然破棺而出朝氓,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布赵哲,位于F島的核電站待德,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏枫夺。R本人自食惡果不足惜将宪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望橡庞。 院中可真熱鬧较坛,春花似錦、人聲如沸扒最。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)扼倘。三九已至确封,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間再菊,已是汗流浹背爪喘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纠拔,地道東北人秉剑。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像稠诲,于是被迫代替她去往敵國(guó)和親侦鹏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

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