应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

JavaNIO三组件SelecotrChannel实现原理解

  一、NIO聊天室入门案例
  在学习原理之前,先来了解一个JavaNIO实现聊天室的小案例,该案例只有三个类:NioServer聊天室服务端、NioClient聊天室客户端、ClientThread客户端线程。服务端代码:Nio聊天室服务端authorcspdate202111304:13下午publicclassNioServer{聊天室成员列表:MapString,SocketChannelmemberChannels;端口privatestaticfinalintPORT8080;选择器privateSelectorselector;管道privateServerSocketChannelserver;缓冲privateByteBufferbuffer;publicNioServer()throwsIOException{初始化Selector选择器this。selectorSelector。open();初始化Channel通道this。servergetServerChannel(selector);初始化Buffer缓冲:this。bufferByteBuffer。allocate(1024);初始化聊天室成员列表memberChannelsnewConcurrentHashMap();}初始化Channel通道paramselectorreturnthrowsIOExceptionprivateServerSocketChannelgetServerChannel(Selectorselector)throwsIOException{开辟一个Channel通道ServerSocketChannelserverSocketChannelServerSocketChannel。open();通道设置为非阻塞模式serverSocketChannel。configureBlocking(false);通道注册绑定Selector选择器,通道中数据的事件类型为OPACCEPTserverSocketChannel。register(selector,SelectionKey。OPACCEPT);通道绑定端口serverSocketChannel。socket()。bind(newInetSocketAddress(PORT));returnserverSocketChannel;}事件监听publicvoidlisten()throwsIOException{System。out。println(服务端启动。。。。。。);try{无限循环while(true){作用:至少需要有一个事件发生,否则(如果count0)就继续阻塞循环intcountselector。select();if(count0){continue;}获取SelectorKey的集合SetSelectionKeykeySetselector。selectedKeys();IteratorSelectionKeyiteratorkeySet。iterator();while(iterator。hasNext()){当前事件对应的SelectorKeySelectionKeykeyiterator。next();删除当前事件:表示当前事件已经被消费了iterator。remove();if(key。isAcceptable()){Accept类型事件:通过key获取ServerSocketChannelServerSocketChannelserver(ServerSocketChannel)key。channel();通过ServerSocketChannel获取SocketChannelSocketChannelchannelserver。accept();channel设置为非阻塞模式channel。configureBlocking(false);channel绑定选择器channel。register(selector,SelectionKey。OPREAD);从channel中获取Host、端口等信息System。out。println(客户端连接:channel。socket()。getInetAddress()。getHostName():channel。socket()。getPort());}elseif(key。isReadable()){Read类型事件SocketChannelchannel(SocketChannel)key。channel();用于解密消息内容CharsetDecoderdecoderCharset。forName(UTF8)。newDecoder();将消息数据从通道channel读取到缓冲bufferByteBufferbufferByteBuffer。allocate(50);buffer。clear();channel。read(buffer);buffer。flip();获取解密后的消息内容:Stringmsgdecoder。decode(buffer)。toString();if(!。equals(msg)){System。out。println(收到:msg);if(msg。startsWith(username)){Stringusernamemsg。replaceAll(username,);memberChannels。put(username,channel);System。out。println(用户总数:memberChannels。size());}else{转发消息给客户端String〔〕arrmsg。split(:);if(arr。length3){发送者Stringfromarr〔0〕;接收者Stringtoarr〔1〕;发送内容Stringcontentarr〔2〕;System。out。println(from发送给to的消息:content);if(memberChannels。containsKey(to)){解密CharsetEncoderencoderCharset。forName(UTF8)。newEncoder();给接收者发送消息memberChannels。get(to)。write(encoder。encode(CharBuffer。wrap(from:content)));}}}}}}}}catch(Exceptione){System。out。println(服务端启动失败。。。。。。);e。printStackTrace();}finally{try{先关闭选择器,在关闭通道调用close()方法将会关闭Selector,同时也会将关联的SelectionKey失效,但不会关闭Channel。selector。close();server。close();}catch(IOExceptione){e。printStackTrace();}}}publicstaticvoidmain(String〔〕args)throwsIOException{服务端启动:newNioServer()。listen();}}客户端线程类:Nio聊天室客户端线程authorcspdate202111304:13下午publicclassClientThreadextendsThread{解密privateCharsetDecoderdecoderCharset。forName(UTF8)。newDecoder();加密privateCharsetEncoderencoderCharset。forName(UTF8)。newEncoder();选择器privateSelectorselectornull;通道privateSocketChannelsocketnull;通道keyprivateSelectionKeyclientKeynull;用户名privateStringusername;publicClientThread(Stringusername){try{创建一个SelectorselectorSelector。open();创建Socket并注册socketSocketChannel。open();socket。configureBlocking(false);clientKeysocket。register(selector,SelectionKey。OPCONNECT);连接到远程地址InetSocketAddressipnewInetSocketAddress(localhost,8080);socket。connect(ip);this。usernameusername;}catch(IOExceptione){e。printStackTrace();}}开辟读取事件的线程Overridepublicvoidrun(){try{监听事件(无限循环)while(true){监听事件selector。select();事件来源列表IteratorSelectionKeyitselector。selectedKeys()。iterator();while(it。hasNext()){SelectionKeykeyit。next();删除当前事件it。remove();判断事件类型if(key。isConnectable()){连接事件SocketChannelchannel(SocketChannel)key。channel();if(channel。isConnectionPending())channel。finishConnect();channel。register(selector,SelectionKey。OPREAD);System。out。println(连接服务器端成功!);发送用户名send(usernamethis。username);}elseif(key。isReadable()){读取数据事件SocketChannelchannel(SocketChannel)key。channel();读取数据ByteBufferbufferByteBuffer。allocate(50);channel。read(buffer);buffer。flip();Stringmsgdecoder。decode(buffer)。toString();System。out。println(收到:msg);}}}}catch(IOExceptione){e。printStackTrace();}finally{关闭try{selector。close();socket。close();}catch(IOExceptione){}}}发送消息parammsgpublicvoidsend(Stringmsg){try{SocketChannelclient(SocketChannel)clientKey。channel();client。write(encoder。encode(CharBuffer。wrap(msg)));}catch(Exceptione){e。printStackTrace();}}关闭客户端publicvoidclose(){try{selector。close();socket。close();}catch(IOExceptione){}}}客户端代码:Nio聊天室客户端authorcspdate2021120917:03:33publicclassNioClient{publicstaticvoidmain(String〔〕args){当前客户端的用户名Stringusernamelufei;为当前客户端开辟一个线程ClientThreadclientnewClientThread(username);client。start();输入输出流BufferedReadersinnewBufferedReader(newInputStreamReader(System。in));try{循环读取键盘输入Stringreadline;while((readlinesin。readLine())!null){if(readline。equals(bye)){client。close();System。exit(0);}发送消息client。send(username:readline);}}catch(IOExceptione){e。printStackTrace();}}}运行测试:
  启动运行测试一下效果!
  服务端先启动,控制台打印:服务端启动。。。。。。
  接着启动客户端,控制台打印:连接服务器端成功!
  这时候服务端会打印客户端的连接信息以及用户名等信息:
  图片
  测试客户端向服务的发送消息,客户端控制台输入Hello我是lufei!,这时候服务端会收到发送过来的消息内容:
  图片
  我们可以再建立一个客户端启动类NioClient2,并将其启动,服务端会收到客户端2的消息:
  图片
  让客户端1和客户端2之间发送消息:
  图片
  图片
  服务端控制台打印:
  图片
  这样,一个简单的聊天室就搭建成功了,如果小伙伴想自行完善,可以把代码拷贝一下,自己去设计自己想要实现的聊天室功能。
  熟悉了NIO通信的小案例之后,我们通过一张图来分析一下其实现原理:
  从图中可以看出,当有读或写等任何注册的事件发生时,可以从Selector中获得相应的SelectionKey,同时从SelectionKey中可以找到发生的事件和该事件所发生的具体的SelectableChannel,以获得客户端发送过来的数据。二、Selector选择器1、Selector继承体系
  NIO中实现非阻塞IO的核心对象是Selector,Selector是注册各种IO事件的地方,而且当那些事件发生时,就是Seleetor告诉我们所发生的事件。
  使用NIO中非阻塞IO编写服务器处理程序,大体上可以分为下面三个步骤:(1)向Selector对象注册感兴趣的事件。(2)从Selector中获取感兴趣的事件。(3)根据不同的事件进行相应的处理。2、Selector选择器的创建
  在聊天室案例的NioServer服务端类中,选择器的初始化创建位于其构造函数中:publicNioServer()throwsIOException{初始化Selector选择器也可以通过实现java。nio。channels。spi。SelectorProvider。openSelector()抽象方法自定义一个Selector。this。selectorSelector。open();初始化Channel通道初始化Buffer缓冲:初始化聊天室成员列表}
  Selector可以通过它自己的open()方法创建,借助java。nio。channels。spi。SelectorProvider类创建一个新的Selector选择器。也可以通过实现java。nio。channels。spi。SelectorProvider类的抽象方法openSelector()来自定义实现一个Selector。Selector一旦创建将会一直处于open状态直到调用了close()方法为止。
  我们跟进这个open()方法:publicabstractclassSelectorimplementsCloseable{protectedSelector(){}该方法返回一个Selector选择器:publicstaticSelectoropen()throwsIOException{通过SelectorProvider构建选择器returnSelectorProvider。provider()。openSelector();}。。。}
  继续向下跟进SelectorProvider。provider()方法:该方法位于SelectorProvider类中吗,可以获取能够构建Selector选择器的SelectorProvider对象publicstaticSelectorProviderprovider(){synchronized(lock){if(provider!null)returnprovider;returnAccessController。doPrivileged(newPrivilegedActionSelectorProvider(){publicSelectorProviderrun(){if(loadProviderFromProperty())returnprovider;if(loadProviderAsService())returnprovider;DefaultSelectorProvider会根据不同的操作系统去创建不同的SelectorProviderprovidersun。nio。ch。DefaultSelectorProvider。create();returnprovider;}});}}
  我们跟进DefaultSelectorProvider。create()方法,它会根据不同的操作系统去创建不同的SelectorProvider:如果是Windows操作系统,则创建的是WindowsSelectorProvider对象。如果是MacOS操作系统,则创建的是KQueueSelectorProvider对象。如果是Linux操作系统,则创建的是EPollSelectorProvider对象。
  例如我使用的是Mac系统,那么跟进create()方法时,进入如下代码:publicclassDefaultSelectorProvider{privateDefaultSelectorProvider(){}publicstaticSelectorProvidercreate(){returnnewKQueueSelectorProvider();}}继续往下跟进KQueueSelectorProvider(),进入KQueueSelectorProvider类:publicclassKQueueSelectorProviderextendsSelectorProviderImpl{publicKQueueSelectorProvider(){}publicAbstractSelectoropenSelector()throwsIOException{KQueueSelectorImpl是具体实现类,我们继续往下跟进,去看看实现逻辑:returnnewKQueueSelectorImpl(this);}}
  继续跟进,进入KQueueSelectorImpl类内部:classKQueueSelectorImplextendsSelectorImpl{用于存放read端的文件描述protectedintfd0;用于存放write端的文件描述protectedintfd1;。。。。。。KQueueSelectorImpl(SelectorProvidervar1){super(var1);makePipe方法是native修饰的本地方法,其作用是返回两个文件描述符var2,var2高位存放的是通道read端的文件描述符,低32位存放的是write端的文件描述符。longvar2IOUtil。makePipe(false);文件描述符fd0只读数据this。fd0(int)(var232);文件描述符fd1只写数据this。fd1(int)var2;。。。。。。}。。。。。。}
  问题:为什么在不同操作系统平台,Provider不同呢?
  因为网络IO是跟操作系统息息相关的,不同的操作系统的实现可能都不一样。比如我们在Linux操作系统安装的JDK版本,和Windows操作系统上就不太一样。3、Selector选择器绑定Channel管道
  如聊天室案例中服务端NioServer,Channel管道与Selector选择器的绑定通过如下方式:初始化Channel通道paramselectorreturnthrowsIOExceptionprivateServerSocketChannelgetServerChannel(Selectorselector)throwsIOException{开辟一个Channel通道ServerSocketChannelserverSocketChannelServerSocketChannel。open();通道设置为非阻塞模式serverSocketChannel。configureBlocking(false);为了将Channel跟Selector绑定在一起,我们需要将Channel注册到Selector上,调用Channel的register()方法通道中数据的事件类型为OPACCEPT(事件类型总共有4种,详情请参考下文的第4小节,管道与选择器之间的桥梁SelectionKey)serverSocketChannel。register(selector,SelectionKey。OPACCEPT);通道绑定端口serverSocketChannel。socket()。bind(newInetSocketAddress(PORT));returnserverSocketChannel;}
  注意:Channel必须是非阻塞模式才能注册到Selector上,所以,无法将一个FileChannel注册到Selector,因为FileChannel没有所谓的阻塞还是非阻塞模式。
  管道Channel和选择器Selector的关系:Selector通过不断轮询的方式同时监听多个Channel的事件,注意,这里是同时监听,一旦有Channel准备好了,它就会返回这些准备好了的Channel,交给处理线程去处理。在NIO编程中,通过Selector我们就实现了一个线程同时处理多个连接请求的目标,也可以一定程序降低服务器资源的消耗。4、管道与选择器之间的桥梁SelectionKey
  我们再来看一下Selector与Channel的关系图:
  图片
  如上图所示,将管道与注册到选择器上时,register()方法需要传递2个参数,一个是Selector选择器对象,另一个是管道中事件的类型SelectionKey,选择器通过该对象的静态变量值去识别不同管道中的事件内容。所以SelectionKey又可以看作是Channel和Selector之间的一座桥梁,把两者绑定在了一起。为了将Channel跟Selector绑定在一起,我们需要将Channel注册到Selector上,调用Channel的register()方法通道中数据的事件类型为OPACCEPTserverSocketChannel。register(selector,SelectionKey。OPACCEPT);
  SelectionKey有如下4种事件类型:读事件:00000001publicstaticfinalintOPREAD10;写事件:00000100publicstaticfinalintOPWRITE12;连接事件:00001000,连接操作,Client端支持的一种操作publicstaticfinalintOPCONNECT13;接受事件:00010000,可接受操作仅ServerSocketChannel支持publicstaticfinalintOPACCEPT14;5、SelectionKey的几个常用方法
  参考文章:https:juejin。cnpost68449034405737922705。1、interestOps()方法作用:返回代表需要Selector监控的IO操作的,可以通过以下方法来判断Selector是否对Channel的某种事件感兴趣。interest数据集:当前Channel感兴趣的操作,此类操作将会在下一次选择器select()操作时被交付,可以通过selectionKey。interestOps(int)进行方法修改。使用方式如下:获取该selectionKey感兴趣的事件集intinterestSetselectionKey。interestOps();booleanisInterestedInAccept(interestSetSelectionKey。OPACCEPT)SelectionKey。OPACCEPT;booleanisInterestedInConnectinterestSetSelectionKey。OPCONNECT;booleanisInterestedInReadinterestSetSelectionKey。OPREAD;booleanisInterestedInWriteinterestSetSelectionKey。OPWRITE;5。2、readyOps()方法作用:获取此selectionKey键上的ready操作集合,即在当前通道上已经就绪的事件。可以通过readyOps()方法获取所有就绪了的事件,也可以通过isXxxable()方法检查某个事件是否就绪。ready数据集:表示此选择键上,已经就绪的操作,每次select()时,选择器都会对ready集合进行更新,外部程序无法修改此集合。使用方式如下:创建ready集合的方法intreadySetselectionKey。readyOps();检查这些操作是否就绪的方法booleanisReadable();是否可读,是返回true,检测此键是否为read事件。等效于:k。,readyOps()OPREAD!0;booleanisWritable():是否可写,是返回truebooleanisConnectable():是否可连接,是返回truebooleanisAcceptable():是否可接收,是返回true5。3、channel()、selector()方法作用:通过channel()、selector()方法可以获取绑定的通道Channel和选择器Selector,代码案例如下:ChannelchannelselectionKey。channel();SelectorselectorselectionKey。selector();5。4、attachment()方法
  可以将一个或者多个附加对象绑定到SelectionKey上,以便容易的识别给定的通道。通常有两种方式:在注册的时候直接绑定:SelectionKeykeychannel。register(selector,SelectionKey。OPREAD,theObject);在绑定完成之后附加:selectionKey。attach(theObject);绑定
  绑定之后,可通过对应的SelectionKey取出该对象:selectionKey。attachment();
  如果要取消该对象,则可以通过该种方式:selectionKey。attach(null)
  需要注意的是如果附加的对象不再使用,一定要人为清除,因为垃圾回收器不会回收该对象,若不清除的话会成内存泄漏。
  一个单独的通道可被注册到多个选择器中,有些时候我们需要通过isRegistered()方法来检查一个通道是否已经被注册到任何一个选择器上。通常来说,我们并不会这么做。
  有点类似于ThreadLocal,可以让不同的线程都拥有一份自己的变量副本,且相互隔离,但是区别在于ThreadLocal的对象过期后会被自动回收的!6、Selector的几个常用方法这一部分参考自这2篇文章:
  https:blog。csdn。nettangtong1articledetails103414499https:blog。csdn。netweixin34237596articledetails927383316。1、select()方法
  一旦将一个或多个Channel注册到Selector上了,我们就可以调用它的select()方法了,它会返回注册时感兴趣的事件中就绪的事件。
  select()方法有三种变体:select(),无参数,阻塞到至少有一个通道在你注册的事件上就绪了才返回。(当然是我们注册的感兴趣的事件)。select(timeout),带超时,阻塞直到某个Channel有就绪的事件了,或者超时了才返回。selectNow(),立即返回,非阻塞,只要有通道就绪就立刻返回。
  select()方法返回的int值表示有多少通道已经就绪,是自上次调用select()方法后有多少通道变成就绪状态。之前在select()调用时进入就绪的通道不会在本次调用中被记入,而在前一次select()调用进入就绪但现在已经不在处于就绪的通道也不会被记入。例如:首次调用select()方法,如果有一个通道变成就绪状态,返回了1,若再次调用select()方法,如果另一个通道就绪了,它会再次返回1。如果对第一个就绪的Channel没有做任何操作,现在就有两个就绪的通道,但在每次select()方法调用之前,只有一个通道就绪了。
  一旦调用select()方法,并且返回值不为0时,则可以通过调用Selector的selectedKeys()方法来访问已选择键集合。如下:SetSelectionKeyselectionKeySetselector。selectedKeys();6。2、selectKeys()方法
  Selector。selectKeys(),可以获取该选择器相关联的SelectionKey集合,通过遍历这些SelectorKey,可以进一步获取其感情兴趣的事件类型,以及其关联的Channel通道。SetSelectionKeyselectedKeysselector。selectedKeys();IteratorSelectionKeyitselectedKeys。iterator();while(it。hasNext()){SelectionKeykeykeyIterator。next();if(key。isAcceptable()){可连接事件}elseif(key。isConnectable()){连接事件}elseif(key。isReadable()){读取数据事件}elseif(key。isWritable()){写入事件}it。remove();}
  最后,一定要记得调用it。remove();移除已经处理的SelectionKey。6。3、wakeUp()方法
  前面我们说了调用select()方法时,调用者线程会进入阻塞状态,直到有就绪的Channel才会返回。其实也不一定,wakeup()就是用来破坏规则的,可以在另外一个线程调用wakeup()方法强行唤醒这个阻塞的线程,这样select()方法也会立即返回。
  如果调用wakeup()时并没有线程阻塞在select()上,那么,下一次调用select()将立即返回,不会进入阻塞状态。这跟LockSupport。unpark()方法是比较类似的。6。4、close()方法
  调用close()方法将会关闭Selector,同时也会将关联的SelectionKey失效,但不会关闭Channel。三、Channel通道1、Channel继承体系
  图片
  通道是一个对象,通过它可以读取和写入数据,当然所有数据都通过Buffer对象来处理。我们永远不会将字节直接写入通道,而是将数据写入包含一个或者多个字节的缓冲区。同样也不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。
  使用NIO读取数据可以分为下面三个步骤:(1)从FileInputStream获取Channel。(2)创建Buffer。(3)将数据从Channel读取到Buffer中。
  使用NIO写入数据同样分为三个步骤:(1)从FileInputStream获取Channel。(2)创建Buffer。(3)将数据从Channel写入Buffer。2、Channel与Steam流的区别
  参考自:https:blog。csdn。nettangtong1articledetails103341597
  BIO是面向流(Stream)编程的,流又分成InputStream和OutputStream,那么Channel和Stream有什么区别呢?Channel可以同时支持读和写,而Stream只能支持单向的读或写(所以分成InputStream和OutputStream)。Channel支持异步读写,Stream通常只支持同步。Channel总是读向(readinto)Buffer,或者写自(writefrom)Buffer(有点绕,以Channel为中心,从Channel中读出数据到Buffer,从Buffer中往Channel写入数据),可以参考如下代码:
  将Channel管道中的数据读取到Buffer:if(key。isReadable()){读取数据事件SocketChannelchannel(SocketChannel)key。channel();读取数据ByteBufferbufferByteBuffer。allocate(50);将管道中的数据读取到缓冲Buffer中:channel。read(buffer);buffer。flip();Stringmsgdecoder。decode(buffer)。toString();System。out。println(收到:msg);}
  将数据通过Buffer写入到Channel管道:发送消息parammsgpublicvoidsend(Stringmsg){try{SocketChannelclient(SocketChannel)clientKey。channel();将数据通过Buffer写入到Channel管道:client。write(encoder。encode(CharBuffer。wrap(msg)));}catch(Exceptione){e。printStackTrace();}}
  由此可知,管道中的数据传输、从管道中读取写入数据,数据本身都是需要包装再Buffer缓冲中的!原文:兴趣使然的草帽路飞
  https:mp。weixin。qq。comsSjn5pUUDUFb0VOFoeGnj1A

中医治疗中风后遗症经方1则,益气养血,化瘀通络【主治】:中风后遗症,气血亏虚,络脉瘀滞型。手指麻木,入睡难,多梦,眠浅早醒,头昏头痛,脑鸣,畏寒,时有短气、心悸、自汗。【方药】:酸枣仁,川芎,知母,茯神,夜交藤,枳壳……健康智能手表didoG28SPro,顶配版全能健康监测智能手欢迎来到数码情报局,局长聊智能手表,今天为大家点一首好听的歌《蝴蝶泉边》,下一期想听什么歌可以在评论区点歌哦!人们生活水平提高,家庭工作压力大,身体素质却越来越差。当前我……冬奥开幕式旗杆下吹小号的男孩是谁?为何选中这群大山里的孩子?昨晚,北京冬奥会开幕式惊艳亮相,再次震惊全世界。据了解,开幕式参演群体中95是青少年,这也传达出一起向未来的清晰理念。开幕式也因为有了孩子们的参演而让人格外印象深刻,下面……白酒啤酒红酒,哪一种酒对肝脏的伤害最小?医生告诉你实情生活中,有人爱喝白酒,有人爱喝啤酒,有人爱喝红酒,这三种酒也是市面上最常见的种类,都说饮酒伤肝,抛去个人喜好不谈,经常有人询问白酒、红酒、啤酒这三种酒哪一种对肝脏的损害最小?……输球后,俱乐部奖励10万!WCBA又上热搜了!因裁判判罚争议最近的WCBA真是一波未平一波又起。前有江苏女篮孙丽被垫脚致重伤,现又有因裁判争议引起了武汉女篮的不满和外界的广泛质疑。侃球君先给大家捋一捋事情的经过;武汉女……线上春节档来了!天龙八部之乔峰传年三十再掀武林风云今天,由甄子丹担任总导演,甄子丹、王晶监制,朱玮杰担任总出品人,甄子丹、陈钰琪、刘雅瑟领衔主演,惠英红特别演出、吴樾特邀主演的武侠巨制《天龙八部之乔峰传》官宣将于大年三十(1月……爱奇艺陷入裁员风波网易云音乐破发阿里原副总裁李永和起诉周某一、独角兽史上最大规模!爱奇艺陷入裁员风波,年年亏损看不到尽头近日,爱奇艺要大规模裁员的消息引发网友热议。据爱奇艺内部人员爆料,情况属实,此次裁员比例在20到40,……韩国新晋第一夫人靠美貌火了!晚宴裙装更好看,摘下口罩颜值绝了韩国新晋第一夫人金建希靠着美貌火了,被誉为是最美韩国第一夫人。而在当地时间周二新总统的就职典礼上,49岁的金建希衣品好,气质好,更是有着一张超级精致的脸。金建希一天换了好几套造……一盘毛肚380成本4块卖上千,这些明星坑起粉丝来真不手软众所周知,相比于其他职业,明星赚的钱要多得多。或许正是应了那句话越富的人欲望越大,不少明星就是如此,利用自己的明星身份大捞特捞,坑起粉丝的钱来,简直是毫不手软。1。林志颖……这个五一,抖音网友最想去的十大景点,雨崩村第一不去天堂,就去雨崩,神仙居住的地方。抖音网友在雨崩村主页这样留言。雨崩村在云南迪庆藏族自治州德钦县云岭乡雨崩景区境内、梅里雪山山脚下,是徒步者的天堂。刚刚过去的五一假期,……今日G5两场天王山,竟变成两场大屠杀今日G5两场天王山,本来以为是火星撞地球,没想到居然演绎成了大屠杀!1、热火120:85主场35分屠杀76人G5全场比分大帝归来,已连赢2场!76人在恩比德复……今秋最in的5双鞋,巴黎女人已经悄悄穿起来啦最近气温骤降,一夜之间秋意正浓。巴黎女人夏日最爱的凉鞋和草编鞋已经被她们放入鞋柜中,以待来年。因为温度原因,不论在颜色还是款式方面,秋冬服装与鞋履的选择范围不会像春夏那般……
全国体操冠军赛收官邹敬园家门口斩获两金4月15日,2022年全国体操冠军赛在成都东安湖体育公园多功能体育馆落幕。本届大赛包含个人全能、自由体操、鞍马、吊环、跳马、双杠、单杠、高低杠、平衡木等多个项目,共产生22枚金……夫妻中有一人是O型血,对方若是这几种血型,宝宝或很幸运结婚生子对每个人来说都是非常重要的人生经历,男女双方建立婚姻关系后,就要考虑孕育后代的问题,繁衍后代走向余下的生活是多数人都要完成的生理过程,双方结合后,生出来的宝宝结合了父母……90年前,短跑王子独自扛着国旗参加奥运会,向世界展示中国犹在2022年冬奥会开幕式,中国有数百名运动员参赛,出场时的中国红,完美地向世界展示了中国的底气与自信。2022年中国代表团然而,1932年,中国第一次参加奥运会却只有……勇士队想要挽留伊戈达拉,主帅科尔表示只要他想随时可以回来伊戈达拉在上个赛季选择重新回到勇士队,初衷就是希望在这里结束自己的职业生涯。而勇士队也是伊戈达拉职业生涯效力时间最长的球队,在这里他随队夺得了4次总冠军,而且还拿到了一次FMV……七夕情人节浪漫寄语七夕情人节浪漫寄语1。我还是很喜欢你,像清晨珠露欲滴,零露湑兮,我心写兮。2。对你的思念太重,压断了电话线,烧坏了手机卡,掏尽了钱包袋,吃光了安眠药,哎!我仍旧止不……张若昀携新剧沉鱼记袭来,杨紫饰演侠女,网友直呼王炸组合张若昀在《庆余年》、《雪中悍刀行》相继爆了之后,张若昀已成为无数人心中的偶像。本以为他会趁热打铁,相继推出《庆余年2》、《雪中悍刀行2》,让阿东万万没想到的没想到他摇身一变,竟……郑爽,你输了!如果说娱乐圈有比郑爽还疯的人,那这个人一定是叶璇。叶璇有多疯?估计也就10个赵樱子吧。只不过,赵樱子是装疯卖傻,而叶璇,那真是疯的不可控制。这不前两天,好久不……荔湾大手牵小手,垃圾分类齐动手!春蕾幼儿园萌娃争做垃圾分类小为培养居民群众垃圾分类良好习惯,近日,龙津街道联合洞神坊社区党委、龙津街垃圾分类指导中心、春蕾幼儿园、龙津街道社工站以及社区志愿者力量,在春蕾幼儿园开展大手牵小手,垃圾分类齐动……乌克兰外长库列巴感觉被骗了据英国《每日快报》网站4月11日报道,温布尔登网球公开赛主办方被指责允许俄罗斯选手参加今年的比赛是给了普京一次胜利。乌克兰外长库列巴在敦促英国政府禁止俄罗斯和白俄罗斯球员入境时……1岁孩子独自在家睡觉,妈妈买菜再见孩子时,发现满身是血照顾孩子是一项艰巨而又充实的任务。作为父母,我们必须承担起孩子的生命和成长责任,无论是在日常生活中还是教育上。但是,在一个人照顾孩子的情况下,这项任务变得更加艰难。孩子需要的不……超级干货!不用魔法和下载!无限次数免费使用ChatGPT!Claude:一款由前OpenAI员工打造的新型聊天机器人Claude是一款由前OpenAI的研究员和工程师开发的新型聊天机器人,它可以执行各种对话和文本处理任务,同时保……鹤峰下坪茶园美如画春日采茶忙湖北日报客户端讯(通讯员肖红霞陈玉玲)春风十里茶飘香,又是一年采茶时。4月11日,鹤峰县下坪乡留驾村茶园里,一片片冒着新绿的茶园中,三两茶农结伴正忙着采摘春茶。一双双巧手在茶树……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网