java NIO写入和读取的数据不一样 丢失了很多数据 怎么解决

java NIO写入和读取的数据不一样 丢失了很多数据 怎么解决

我把图片对象存入Bytebuffer, 发到服务器读取后,很多图片都是不完整的

1个回答

Java 读取 C++写入的二进制数据
----------------------biu~biu~biu~~~在下问答机器人小D,这是我依靠自己的聪明才智给出的答案,如果不正确,你来咬我啊!

qq_26946497
谁用了我的英文名 一块咬^_^
4 年多之前 回复
lf546619395
终极范特西 咬死你
4 年多之前 回复

求大神给点思路~~~~~

qq_26946497
谁用了我的英文名 虽然我也不知道为什么,但问题描述这样模糊是没有办法回答的!
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
java NIO通信 客户端为什么收不到数据

客户端程序 public class NioSelectorClient { public static void main(String[] args) throws IOException{ SocketChannel channel = SocketChannel.open(); channel.configureBlocking(false); Selector selector = Selector.open(); channel.connect(new InetSocketAddress("127.0.0.1", 7777)); channel.register(selector,SelectionKey.OP_CONNECT|SelectionKey.OP_READ); System.out.println("============读===AAAA======"); while(true) { int n = selector.select(); if(n==0) continue; Iterator<SelectionKey> iter = selector.selectedKeys().iterator(); while(iter.hasNext()){ SelectionKey key = iter.next(); if(key.isConnectable()) { System.out.println("================连接成功了==============="); } if( key.isReadable()) { System.out.println("=========数据来了============"); SocketChannel client = (SocketChannel)key.channel(); ByteBuffer buf = ByteBuffer.allocate(1024); int a= client.read(buf); buf.flip(); byte[] b = new byte[a]; System.arraycopy(buf.array(), 0, b, 0, a); String s = new String(b); System.out.println("============读描述符有数据了======服务器发来的数据:"+s); } iter.remove(); } } } } 服务端程序 public class NioSelectorServer { public static void main(String[] args) throws IOException { // 创建一个selector选择器 Selector selector = Selector.open(); SocketChannel clientchannel = null; // 打开一个通道 ServerSocketChannel serverchannel = ServerSocketChannel.open(); // 使设定non-blocking的方式。 serverchannel.configureBlocking(false); serverchannel.socket().bind(new InetSocketAddress(7777)); // 向Selector注册Channel及我们有兴趣的事件 serverchannel.register(selector, SelectionKey.OP_ACCEPT); while(true) { int n = selector.select(); if (n != 0) { Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) (it.next()); if (key.isAcceptable()) { System.out.println("=====服务端========连接了======="); ServerSocketChannel Serverchannel = (ServerSocketChannel) key.channel(); clientchannel = Serverchannel.accept(); clientchannel.configureBlocking(false); clientchannel.register(selector, SelectionKey.OP_WRITE); } if(key.isWritable()) { System.out.println("=============服务端===========可写========="); SocketChannel client = (SocketChannel) key.channel(); String ss = "客户端 你好"; client.write(ByteBuffer.wrap(ss.getBytes())); } it.remove(); } } } } } 在本地运行 为什么客户端一直收不到服务端发来的数据了,到底程序错在哪了 ,请大家帮忙指点,最好将我的错误代码改正过来,万分感谢!!!

java nio socket 异步接收数据

nio socket 异步接收数据,如何确定收接的数据,就是发送的返回的?有谁研究过没。

求教Java.Nio 中SocketChannel 写入数据的问题

### 请问SocketChannel 写入大一点的数据时该如何处理 ![图片说明](https://img-ask.csdn.net/upload/201901/18/1547780789_544042.png) ###这个方法如何用循环完善,不然数据稍微大点就会报错 /** * 把指定的字符串按照默认编码转化成byte字节流写入到socket channel中 * @param channel * @param buffer * @param str * @throws IOException */ public static void wirteCmd(SocketChannel channel,ByteBuffer buffer,String str) throws IOException{ buffer.clear(); byte[] bytes=str.getBytes(); buffer.put(bytes); buffer.flip(); channel.write(buffer); buffer.clear(); } ``` ```

java nio 如何实现 阻塞读 不阻塞写

java nio 如何实现 阻塞读 不阻塞写 java nio 如何实现 阻塞读 不阻塞写

关于Java的nio的FileChannel类读取数据的问题

本人新手,在使用nio时出现了一些问题。在nio的api中,有一个FileChannel类,其中的read方法说明是非阻塞的,但是我在使用的时候它却是阻塞在程序中了,不知道为什么出现这样错误。还有就是,在api中的read方法说明可以在另外线程关闭通道而导致此正在使用的read方法抛出异常。可是我使用的时候它并没有抛出,仍然阻塞在那里。我看的不是盗版api吧。。。期待大神的解答!!!十分感谢!!!

java nio 业务接收多线程处理是否必要

<p>nio在服务器收到客户端请求的时候,是单线程的,即使自己在后续的业务流程处理中使用了线程池操作,由于接收部分是单线程的,也没有什么意义?有何办法提高效率?</p>

java nio selector怎么达到与Linux select一样的效果

前几天做了一个linux下的socket实验使用了select,可以让程序在不使用多线程的情况下,实现io的异步,也就是可以收数据,也可以发数据,但不阻塞。 于是我就想能不能移植到Java下来实现。结果我发现Java也有select类似的功能,但是我发现Java nio的Chanel无法对标准输入进行处理,要发数据的时候就会阻塞。 可能是我技术不够,我想问问大家Java nio到底能不能实现与linux select一样的效果? package server; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Scanner; import java.nio.ByteBuffer; import java.nio.channels.Channel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; public class ServerSock { public ServerSock() { // TODO Auto-generated constructor stub try { ServerSocketChannel server= ServerSocketChannel.open(); server.bind(new InetSocketAddress(InetAddress.getLocalHost(), 8899), 5); System.out.println("服务器启动...."); Selector selector = Selector.open(); server.configureBlocking(false); server.register(selector, SelectionKey.OP_ACCEPT); ByteBuffer buf = ByteBuffer.allocate(48); SocketChannel channel = null; while(true){ int a=selector.select(); Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator(); while(keyIter.hasNext()){ SelectionKey key = keyIter.next(); if (key.isAcceptable()) { channel = server.accept(); System.out.println("接受: "); channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); }else if (key.isReadable()) { System.out.println("读取:"); int bytesRead = channel.read(buf); buf.flip(); String aString = new String(buf.array()).trim(); System.out.println(aString); buf.clear(); }else if (key.isWritable()) { System.out.println("写入:"); Scanner scanner = new Scanner(System.in); String b = scanner.nextLine(); buf.put(b.getBytes()); buf.flip(); channel.write(buf); buf.clear(); } keyIter.remove(); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { new ServerSock(); } } ``` ```

java nio的select和linux的epoll有什么区别?

#### 最近在看关于epoll和select相关问题,但是并没有发现java的select和linux的epoll有什么区别 #### java的nio select代码如下 ``` import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.UUID; public class NioServer { private static Map<String, SocketChannel> clientMap = new HashMap<>(); public static void main(String[] args) throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); ServerSocket serverSocket = serverSocketChannel.socket(); serverSocket.bind(new InetSocketAddress(8899)); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { try { /** * 程序会卡在select()函数,当客户端有动作了,比如连接上了,或者是发送消息过来了,服务端才会继续走 * 当第一个客户端连接上并且是selectionKey.isAcceptable(),代码就又重新卡到了select()函数上 * 等待客户端的再次操作(无论是哪个客户端) */ selector.select(); /** * selector.selectedKeys()这段代码可以从中知道是哪个客户端,执行了什么操作 * */ Set<SelectionKey> selectionKeys = selector.selectedKeys(); selectionKeys.forEach((selectionKey) -> { final SocketChannel client; try { if (selectionKey.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel(); /** * 这代代码获取了真正的客户端socket句柄 */ client = server.accept(); client.configureBlocking(false); /** * 这句话如果不写,就相当于没有注册当消息可读时的回调函数,当客户端发送消息过来的时候 * 服务端的selector.selectedKeys()就永远不会受到这类消息 */ client.register(selector, SelectionKey.OP_READ); String key = "[" + UUID.randomUUID().toString() + "]"; clientMap.put(key, client); } else if (selectionKey.isReadable()) { client = (SocketChannel) selectionKey.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1024); int count = client.read(readBuffer); if (count > 0) { readBuffer.flip(); Charset charset = Charset.forName("utf-8"); String recvMsg = String.valueOf(charset.decode(readBuffer).array()); System.out.println(client + ":" + recvMsg); String sendKey = null; for (Map.Entry<String, SocketChannel> stringSocketChannelEntry : clientMap.entrySet()) { if (stringSocketChannelEntry.getValue() == client) { sendKey = stringSocketChannelEntry.getKey(); break; } } for (Map.Entry<String, SocketChannel> stringSocketChannelEntry : clientMap.entrySet()) { SocketChannel socketChannel = stringSocketChannelEntry.getValue(); ByteBuffer writeBuffer = ByteBuffer.allocate(1024); writeBuffer.put((sendKey + ": " + recvMsg).getBytes()); writeBuffer.flip(); socketChannel.write(writeBuffer); } } } } catch (Exception ex) { ex.printStackTrace(); } }); selectionKeys.clear(); } catch (Exception e) { e.printStackTrace(); } } } } ``` #### linux的epoll的c代码如下 ``` #include <iostream> #include <sys/socket.h> #include <sys/epoll.h> #include <netinet/in.h> #include <arpa/inet.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <errno.h> #include <cstring> using namespace std; #define MAXLINE 5 #define OPEN_MAX 100 #define LISTENQ 20 #define SERV_PORT 5000 #define INFTIM 1000 void setnonblocking(int sock) { int opts; opts=fcntl(sock,F_GETFL); if(opts<0) { perror("fcntl(sock,GETFL)"); exit(1); } opts = opts|O_NONBLOCK; if(fcntl(sock,F_SETFL,opts)<0) { perror("fcntl(sock,SETFL,opts)"); exit(1); } } int main(int argc, char* argv[]) { int i, maxi, listenfd, connfd, sockfd,epfd,nfds, portnumber; ssize_t n; char line[MAXLINE]; socklen_t clilen; if ( 2 == argc ) { if( (portnumber = atoi(argv[1])) < 0 ) { fprintf(stderr,"Usage:%s portnumber/a/n",argv[0]); return 1; } } else { fprintf(stderr,"Usage:%s portnumber/a/n",argv[0]); return 1; } //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件 struct epoll_event ev,events[20]; //生成用于处理accept的epoll专用的文件描述符 //创建一个epoll文件描述符 epfd=epoll_create(256); struct sockaddr_in clientaddr; struct sockaddr_in serveraddr; listenfd = socket(AF_INET, SOCK_STREAM, 0); //把socket设置为非阻塞方式 //setnonblocking(listenfd); //设置与要处理的事件相关的文件描述符 ev.data.fd=listenfd; //设置要处理的事件类型 ev.events=EPOLLIN|EPOLLET; //ev.events=EPOLLIN; //注册epoll事件,将socket文件描述符listenfd的ev事件注册到epoll上 epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev); memset(&serveraddr, sizeof(serveraddr) ,0); serveraddr.sin_family = AF_INET; char *local_addr="127.0.0.1"; inet_aton(local_addr,&(serveraddr.sin_addr));//htons(portnumber); serveraddr.sin_port=htons(portnumber); //先bind再监听 bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr)); listen(listenfd, LISTENQ); maxi = 0; for ( ; ; ) { //等待epoll事件的发生 //param epfd表示将监听epfd的事件 //param events表示容器,一旦有事件发生,events数组会被填充 nfds=epoll_wait(epfd,events,20,500); //处理所发生的所有事件 for(i=0;i<nfds;++i) { if(events[i].data.fd==listenfd)//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。 { connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen); if(connfd<0){ perror("connfd<0"); exit(1); } //setnonblocking(connfd); char *str = inet_ntoa(clientaddr.sin_addr); cout << "accapt a connection from " << str << endl; //设置用于读操作的文件描述符 ev.data.fd=connfd; //设置用于注测的读操作事件 ev.events=EPOLLIN|EPOLLET; //ev.events=EPOLLIN; //注册ev epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); } else if(events[i].events&EPOLLIN)//如果是已经连接的用户,并且收到数据,那么进行读入。 { cout << "EPOLLIN" << endl; if ( (sockfd = events[i].data.fd) < 0) continue; if ( (n = read(sockfd, line, MAXLINE)) < 0) { if (errno == ECONNRESET) { close(sockfd); events[i].data.fd = -1; } else std::cout<<"readline error"<<std::endl; } else if (n == 0) { close(sockfd); events[i].data.fd = -1; } line[n] = '/0'; cout << "read " << line << endl; //设置用于写操作的文件描述符 ev.data.fd=sockfd; //设置用于注测的写操作事件 ev.events=EPOLLOUT|EPOLLET; //修改sockfd上要处理的事件为EPOLLOUT //epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); } else if(events[i].events&EPOLLOUT) // 如果有数据发送 { sockfd = events[i].data.fd; write(sockfd, line, n); //设置用于读操作的文件描述符 ev.data.fd=sockfd; //设置用于注测的读操作事件 ev.events=EPOLLIN|EPOLLET; //修改sockfd上要处理的事件为EPOLIN epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); } } } return 0; } ``` #### 从上面两段代码看好像基本思想都是一样的,并没有传说中的select不知道发生的事件,只能通过循环去判断的情况。 #### 但是后来我又在网上找了一段linux的select实现的网络io代码 ``` #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<unistd.h> #include<stdlib.h> #include<errno.h> #include<arpa/inet.h> #include<netinet/in.h> #include<string.h> #include<signal.h> #define MAXLINE 1024 #define LISTENLEN 10 #define SERV_PORT 6666 int main(int argc, char **argv) { int i, maxi, maxfd, listenfd, connfd, sockfd; int nready, client[FD_SETSIZE]; ssize_t n; fd_set rset, allset; char buf[MAXLINE]; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)); listen(listenfd, LISTENLEN); maxfd = listenfd; /* initialize */ maxi = -1; /* index into client[] array */ for (i = 0; i < FD_SETSIZE; i++) client[i] = -1; /* -1 indicates available entry */ FD_ZERO(&allset); FD_SET(listenfd, &allset); for ( ; ; ) { rset = allset; /* structure assignment */ nready = select(maxfd+1, &rset, NULL, NULL, NULL); if (FD_ISSET(listenfd, &rset)) /* new client connection */ { clilen = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr*) &cliaddr, &clilen); #ifdef NOTDEF printf("new client: %s, port %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, 4, NULL), ntohs(cliaddr.sin_port)); #endif for (i = 0; i < FD_SETSIZE; i++) if (client[i] < 0) { client[i] = connfd; /* save descriptor */ break; } if (i == FD_SETSIZE) { printf("too many clients"); exit(0); } FD_SET(connfd, &allset); /* add new descriptor to set */ if (connfd > maxfd) maxfd = connfd; /* for select */ if (i > maxi) maxi = i; /* max index in client[] array */ if (--nready <= 0) continue; /* no more readable descriptors */ } for (i = 0; i <= maxi; i++) /* check all clients for data */ { if ( (sockfd = client[i]) < 0) continue; if (FD_ISSET(sockfd, &rset)) { if ( (n = read(sockfd, buf, MAXLINE)) == 0)/* connection closed by client */ { close(sockfd); FD_CLR(sockfd, &allset); client[i] = -1; } else write(sockfd, buf, n); if (--nready <= 0) break; /* no more readable descriptors */ } } } } ``` #### 从这段代码里面确实是可以看出是通过循环判断的,我的问题是java的select是不是就是linux的epoll的思想?

java读取大文件csv格式

有一个2g的文件,传统io读写可能出问题,所以我想用nio方法先分割,生成temp文件,然后读取每个temp。 但是因为这个文件里面一条record不是按照行来分隔,比较乱,要写代码去判断如何分隔。 有没有什么其他好的办法读取文件?

JAVA NIO channel中同时执行两个写操作

NIO中设置 channel.register(this.selector,SelectionKey.OP_WRITE); 在相应的方法中,同时执行两个写操作 if (selectionKey.isWritable()){ write(selectionKey); writequotation(selectionKey); }

java nio selector.select不阻塞

# java nio selector.select不阻塞 java nio 构建的服务端在与客户端(用ubuntu虚拟机的netcat)连接上后, netcat直接ctrl + d(什么内容都不输入)的话,服务端的selector.select()方法的结果就一直是0 也不阻塞了。请问这是为什么。 代码如下: ```java package chapter4; import org.junit.Test; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; public class List4_2 { @Test public void test1(){ PlainNIOServer server = new PlainNIOServer(); try { server.serve(12345); } catch (IOException e) { e.printStackTrace(); } } private static class PlainNIOServer { public void serve(int port) throws IOException {//在对方连接上以后直接ctrl+d会陷入readable的死循环 ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.configureBlocking(false); serverChannel.bind(new InetSocketAddress(port)); Selector selector = Selector.open(); serverChannel.register(selector, SelectionKey.OP_ACCEPT); while(true){ if (selector.select() == 0){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // continue; } Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while (it.hasNext()){ SelectionKey key = it.next(); it.remove(); System.out.println("acc : " + key.isAcceptable() + ", w : " + key.isWritable() + ", r : " + key.isReadable() + ", conn : " + key.isConnectable() + ", v : " + key.isValid()); try { if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel client = server.accept(); if (client != null) { client.configureBlocking(false); client.register(selector, SelectionKey.OP_READ); System.out.println("Accept Connection from " + client); } } if (key.isReadable()) { SocketChannel client = (SocketChannel) key.channel(); ByteBuffer byteBuffer = ByteBuffer.allocate(5); System.out.println("readable !!!"); int count = 0; while (( count = client.read(byteBuffer)) > 0 ) { byteBuffer.flip(); byte[] bytes = new byte[1024]; while (byteBuffer.hasRemaining()) { byteBuffer.get(bytes, 0, Math.min(byteBuffer.remaining(), bytes.length)); String sentence; System.out.println(sentence = new String(bytes, 0, count)); byteBuffer.compact(); byteBuffer.put(sentence.getBytes()); byteBuffer.flip(); client.write(byteBuffer); } byteBuffer.compact(); } } } catch (Exception e){ e.printStackTrace(); key.channel().close(); } } } } } } ``` 运行如上代码以后,在虚拟机里运行netcat , 截图如下 ![图片说明](https://img-ask.csdn.net/upload/201806/23/1529747149_870890.png) 此时在netcat中按下ctrl + d (EOF)则服务端的selector.select方法调用之后返回结果一直为0且不再阻塞,所有连上的客户端也没办法发消息了。 服务端效果如下: ![图片说明](https://img-ask.csdn.net/upload/201806/23/1529747418_255698.png)

java NIO 多线程

<div class="iteye-blog-content-contain" style="font-size: 14px;"> <pre name="code" class="java">public void run() { exitRequest = false ; while( !exitRequest) { try { // 初期化 socketChannel = SocketChannel.open() ; selector = Selector.open() ; socketChannel.socket().setReuseAddress( true) ; socketChannel.configureBlocking( false) ; socketChannel.socket().setReceiveBufferSize( RECV_BUFFER) ; selectionKey = socketChannel.register( selector, SelectionKey.OP_CONNECT) ; selectionKey.attach( new SocketNioControl( notifyObject, selector, socketChannel, selectionKey)) ; socketChannel.connect( inetAddress) ; int timer = 0 ; while( !socketChannel.isConnected()) { selector.select(100) ; if( exitRequest) { break ; } for( SelectionKey key : selector.selectedKeys()) { if( key.isConnectable()) { SocketChannel socketChannel = ( SocketChannel)key.channel() ; SocketNioControl socketControl = ( SocketNioControl)key.attachment() ; socketChannel.finishConnect() ; key.interestOps( SelectionKey.OP_READ) ; socketControl.connect() ; break ; } } if( timer &gt;= TIMER_CONNECT * 1000) { throw new ConnectException() ; } timer += 100 ; } try { while( !exitRequest) { selector.select() ; for( SelectionKey key : selector.selectedKeys()) { SocketNioControl socketControl = ( SocketNioControl)key.attachment() ; if( key.isReadable()) { socketControl.read() ; } if( key.isWritable()) { socketControl.write() ; } } } } catch ( ConnectException ioex) { } catch ( CancelledKeyException ckex) { } } catch ( UnknownHostException uhex) { ErrorMessage.logging( uhex) ; } catch ( Exception ex) { ErrorMessage.logging( ex) ; } finally { try { for( SelectionKey key : selector.keys()) { SocketNioControl socketControl = ( SocketNioControl)key.attachment() ; socketControl.disconnect() ; } if( selector != null) { selector.close() ; selector = null ; } for( int timer = 0; timer &lt; TIMER_RETRY * 1000; timer += 100) { Thread.sleep( 100) ; if( exitRequest) { break ; } } } catch( IOException ioe) { } catch( InterruptedException iex) { } } } }</pre> <p> 线程一直被占用,导致系统hungup.是哪里出问题呢?另外<span style="font-family: monospace; font-size: 1em; line-height: 1.5;"> selector.select() 的值一直是0;</span><span style="font-family: monospace; font-size: 1em; line-height: 1.5;">这一句是起什么作用的?</span></p> </div>

Socketchannel写入/读取大量数据问题

我有一个客户端,一个服务端,现在要在服务端截图给客户端,每张图片大概20W字节(200KB)不到 请问socketchannel可以一次性写入这20W字节吗, 就是socketchannel.write(bytebuffer); bytebuffer的limit就是20W不到,这样写入会不会出问题 顺便问问socketchannel的write是异步的吗。。看源码怎么是一个抽象方法

java 关于NIO实现UDP数据传输问题 ,急谢谢,C币不足请不要介意

各位大侠好,小弟想问一下问题,搞了一两天没有搞明白的。因为要实现一个UDP传输服务端,于是在网上找了很多资料然后就写了一个。但是写好之后发现有两个很严重的问题,希望各位大哥给点意见或者思路去解决。 问题一:启动服务端,同时也启动客户端,客户端传输数据服务器正常接收,但是断开客户端后,再启动客户端,服务器就收不到任何客户端发送的消息,好像是服务器关闭了UDP一样,但是重启服务器后(重新打开UDP)客户端既可以发送信息过来。 问题二:多个客户端。第一个客户端连接上后,第二个客户端怎么也链接不上了。即使关闭了第一个客户端也一样。 如下是代码: package com.gateway.socket; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.Iterator; import java.util.Set; import org.apache.log4j.Logger; public class UDPEchoServerSelector extends Thread { private static final Logger log = Logger.getLogger(ServerSocket.class); // private InetSocketAddress inetSocketAddress; // socket处理类 private UDPSocketHandler handler = new UDPSocketHandler(); // 注册的接受服务 private SocketReceiver receiver = null; /** * 初始化socket * * @param receiver * @param hostname * @param port * @throws IOException * @throws UnknownHostException */ public UDPEchoServerSelector(SocketReceiver receiver, String hostname, int port) { if (hostname.isEmpty()) { inetSocketAddress = new InetSocketAddress(port); } else { inetSocketAddress = new InetSocketAddress(hostname, port); } this.receiver = receiver; } @Override public void run() { try { Selector selector = Selector.open(); // 创建选择器,可以处理多路通道。 DatagramChannel serverSocketChannel = DatagramChannel.open(); // 打开通道 serverSocketChannel.configureBlocking(false); // 非阻塞 serverSocketChannel.socket().bind(inetSocketAddress); /* * 将通道管理器和该通道绑定,并为该通道注册SelectionKey.OP_READ事件,注册该事件后, * 当该事件到达时,selector.select()会返回,如果该事件没到达selector.select()会一直阻塞。 */ serverSocketChannel.register(selector, SelectionKey.OP_READ, new ClientData()); log.info("Server: socket server started."); /* * 采用轮询的方式监听selector上是否有需要处理的事件,如果有,则进行处理 */ while (true) { // 轮询 // 当注册的事件到达时,方法返回;否则,该方法会一直阻塞 int nKeys = selector.select(); if (nKeys == 0) { continue; } // 得到选择键列表 Set Keys = selector.selectedKeys(); Iterator it = Keys.iterator(); while (it.hasNext()) { SelectionKey key = null; key = (SelectionKey) it.next(); // 键为位掩码 it.remove(); // 客户端请求连接事件 if (key.isValid() && key.isWritable()) { log.info("Server: SelectionKey is acceptable."); handler.handleWrite(key); } if (key.isReadable()) {// 获得了可读的事件 log.info("Server: SelectionKey is readable."); handler.receiveMsg(key, receiver); } } Keys.clear(); } } catch (IOException e) { e.printStackTrace(); } } public static class ClientData { public SocketAddress clientAddress; public ByteBuffer buffer = ByteBuffer.allocate(255); } } package com.gateway.socket; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import org.apache.log4j.Logger; import com.gateway.common.DeviceDataTools; import com.gateway.common.data.HexUtils; import com.gateway.socket.UDPEchoServerSelector.ClientData; /** * * 处理socket类 * * @author Andy * */ public class UDPSocketHandler { private static Logger log = Logger.getLogger(UDPSocketHandler.class); /** * 链接请求 * * @throws IOException */ public void handleWrite(SelectionKey key) { try { DatagramChannel channel = (DatagramChannel) key.channel(); ClientData clntDat = (ClientData) key.attachment(); clntDat.buffer.flip(); // 从起始位置开始发送 int bytesSent; bytesSent = channel.send(clntDat.buffer, clntDat.clientAddress); if (bytesSent != 0) { key.interestOps(SelectionKey.OP_READ); // 关注客户端发送数据 } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 读请求 * * @throws IOException */ public void receiveMsg(SelectionKey key, SocketReceiver receiver) { ByteBuffer byteBuffer = ByteBuffer.allocate(1024); byteBuffer.clear(); DatagramChannel socketChannel = (DatagramChannel) key.channel(); //非阻塞 try { socketChannel.configureBlocking(false); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println("channel code:" + socketChannel.hashCode()); try { while (true) { InetSocketAddress client = (InetSocketAddress) socketChannel .receive(byteBuffer); byteBuffer.flip(); // byteBuffer中传过来的是10进制的bytep[] byte[] dst = new byte[byteBuffer.limit()]; byteBuffer.get(dst); // 将10进制的byte[]转化成16进制字符串 String data = HexUtils.converBytesToHex(dst); System.out.println(data); log.info("Server: data1 = " + data); byteBuffer.clear(); receiver.udpreceive(socketChannel, data, client); break; } } catch (java.io.IOException e) { //e.printStackTrace(); //this.closeChannel(key, socketChannel); } catch (Exception e) { //e.printStackTrace(); //this.closeChannel(key, socketChannel); } } /** * * @param socketChannel */ private void closeChannel(SelectionKey key, DatagramChannel socketChannel) { try { while (socketChannel.isOpen()) { key.cancel(); socketChannel.close(); } } catch (IOException e1) { e1.printStackTrace(); } } /** * 根据socketKey从内存中获取channel,通过channel向client端发送消息 * * @param socketKey * 内存在channel对应的key * @param data * 发送的数据 * @return * @throws IOException */ public static boolean send(String socketKey, String data) throws IOException { DatagramChannel socketChannel = SocketChannelMapper .getUDPChannel(socketKey); if (socketChannel == null || !socketChannel.isOpen()) { return false; } InetSocketAddress client = SocketChannelMapper .getUDPInetSocketAddress(socketKey + "address"); boolean f = socketChannel.isConnected(); ByteBuffer byteBuffer = ByteBuffer.wrap(DeviceDataTools.hex2Byte(data)); if (f) { socketChannel.write(byteBuffer); } else { socketChannel.connect(new InetSocketAddress(client.getAddress(), client.getPort())); socketChannel.send(byteBuffer, client); } return true; } /** * 根据socketKey从内存中获取channel,通过channel向client端发送消息 * * @param socketKey * 内存在channel对应的key * @param data * 发送的数据 * @return * @throws IOException */ public static boolean send(DatagramChannel socketChannel, String data, InetSocketAddress client) throws IOException { if (socketChannel == null) { return false; } System.out.println("#########################ADDRESS" + client.getAddress()); System.out.println("#########################PORT" + client.getPort()); boolean f = socketChannel.isConnected(); ByteBuffer byteBuffer = ByteBuffer.wrap(DeviceDataTools.hexStr2ByteArray(data)); if (f) { socketChannel.write(byteBuffer); } else { socketChannel.connect(new InetSocketAddress(client.getAddress(), client.getPort())); socketChannel.send(byteBuffer, client); } return true; } }

java nio reactor疑惑

1:最近学习Java nio的线程模型 参考了很多资料 都提到了reactor模式 有个疑问 这里的reactor模式(包括单线程reactor模式多线程reactor模式主从reactor模式) 这个是由java nio实现的 还是需要开发的时候自己封装成reactor模式的nio框架? 2:reactor模式我的理解是把网络IO放在了内核中执行 轮询selector会有注册的感兴趣的 OP_ACCEPT OP_Read等的selectionKey。真正提高的是以非阻塞的方式读取IO,完成后会 触发事件通知selector,之后的业务处理还是可以另起线程池来处理。所以才说selector模式 降低的是网络IO的开销。不知道这样理解对不对 希望大神不吝赐教

java nio 注册读写问题

我知道在nio里面的selector中注册感兴趣的事件,就当注册的事件发生时就执行相应的逻辑。 但是我看到网上很多代码演示都是在执行了可读事件以后就注册成可写事件,执行了可写事件后再注册成可读事件。 但是我的系统中,并不确定下次事件是可读还是可写的,也就是说,发生了一次可读事件,但并不确定下次我是要写还是要读。如果我注册成既可读又可写的话,cpu就飙到了100%。。。 现在我很纠结,不知道正确的处理方法是怎样,我只是简单的加了个Thread.sleep();不过好像这样不太好啊·· 求解决办法···· 谢谢了!!!

java nio通信问题如何解决

大佬们帮我看看这句代码,我有点理解不了:![图片说明](https://img-ask.csdn.net/upload/201706/02/1496365514_646261.png) 这句代码的前面是获取欲与服务器端建立联系的selectionkey的作用,但是server.accept()这句代码并没有和相应的selectionkey对应,jdk只是说这句代码的作用只是获取此刻与服务器channel建立连接的socketchannel而不是此刻正在被检查的selectionkey的对应的socketchannel,那前面的那句sk.isAccpetable()不就起不到作用了吗?请知道的大侠告诉下。代码如下: public class NServer { //用于检测所有Channel状态的Selector private Selector selector=null; static final int PORT=3334; //定义实现编码、解码的字符集对象 private Charset charset=Charset.forName("UTF-8"); public void init() { try { selector=Selector.open(); //通过open方法来打开一个未绑定的ServerSocketChannel实例 ServerSocketChannel server=ServerSocketChannel.open(); InetSocketAddress isa=new InetSocketAddress("127.0.0.1",PORT); //将该ServerSocketChannel绑定到指定IP地址 server.bind(isa); //设置ServerSocket以非阻塞方式工作 server.configureBlocking(false); //将server注册到指定的Selector对象 server.register(selector,SelectionKey.OP_ACCEPT); while(true) //说明有需要处理的IO对象 { if(selector.select()==0)continue; //依次处理selector上的每个选择的SelectionKey for(SelectionKey sk :selector.selectedKeys()) { //从selector上的已选择Key集中删除正在处理的SelectionKey selector.selectedKeys().remove(sk); //如果sk对应的Channel包含客户端的连接请求 if(sk.isAcceptable()) { //调用accept方法接受连接,产生服务端的SocketChannel SocketChannel sc=server.accept(); //设置采用非阻塞模式 if (sc == null) { continue; } sc.configureBlocking(false); //将该SocketChannel也注册到selector //后面的read表示我们可以向通道那里读入数据了 // System.out.println("@@@@@@@@@@@@"); sc.register(selector, SelectionKey.OP_READ); //将sk对应的Channel设置成准备接收其他请求 //sk.interestOps(SelectionKey.OP_ACCEPT); } //如果sk对应的Channel有数据需要读取 if(sk.isReadable()) { //System.out.println("@@@@@@@@@@@@"); //获取该SelectionKey对应的Channel,该Channel中有可读的数据 SocketChannel sc=(SocketChannel) sk.channel(); //定义准备执行读取数据的ByteBuffer ByteBuffer buff=ByteBuffer.allocate(1024); String content=""; //开始读取数据 try { while(sc.read(buff)>0) { buff.flip(); content+=charset.decode(buff); } //打印从该sk对应的Channel里读取到的数据 while(sc.write(buff)>0) { buff.clear(); content+=charset.decode(buff); } //将sk对应的Channel设置成准备下一次读取 sk.interestOps(SelectionKey.OP_READ); System.out.println("Server收到信息了: "+content); if(content.length()<5) { sc.write(charset.encode("你发过来的长度小于5")); } else if(content.length()<9) { sc.write(charset.encode("你发过来的长度小于9")); } }catch(IOException ex) { //从Selector中删除指定的SelectionKey sk.cancel(); if(sk.channel()!=null) { sk.channel().close(); } } //sc.write(charset.encode(line)); } } } } catch (IOException e) { // TODO 自动生成的 catch 块 //System.out.println("出错了"); e.printStackTrace(); } } class Thread3 extends Thread { public void run() { init(); System.out.println("结束了"); } } public static void main(String[]args) { new NServer().new Thread3().start(); } }

java NIO 缓冲区满了怎么办?

客户端一次性向服务器传输大量数据时:如(缓冲区只有50;但是要写入的数据却为几万),虽然数据会被分成大小不一的包,有的小于缓冲区,有的却会大于缓冲区,导致超出缓冲区的数据部分丢失,应该怎么办呢?

java NIO服务器并发编程

各位CSDN的编程大神们!求帮忙,求解决方案!跪求! 最近开发一个基于nio的服务器端程序(也包括客户端),实现一个多人(很多人)并发进行即时通讯的东东。。。发觉这个NIO太难搞了,不过总算还是能够建立一个连接发发“hello world”之类的东西,但是问题来了。由于NIO是针对缓冲区进行操作的,所有数据只能够写入到缓冲区中(我用的是byteBuffer),完了我自定义了一个数据包的格式,如下:|包头一个字节|包长度四个字节|包内容长度可变|包尾一个字节|, 然后在客户端或者服务器端根据这个包长度的数据域去数据进行组包(很多原因啦,比如说为了处理粘包问题啊,还有限定每次传递的数据包大小啊之类的)。缓冲区固然好,但就是这个粘包的问题不好搞。我想到一个办法:每次首先读取包头,根据包头中给出的包长度再去读取包数据,但是我在想要是出现包头到了,但是包的内容信息还没有发送过来,那我得要重新把包头放回缓冲区,等待下一次再读取么?如何放回去呢? 如果不放回去的话,由于服务器端是多用户并发的,下一次(readable)事件到来的时候,我就不知道这个是上一次只读取了包头的那个通道呢还是一个新的通道,那处理起来就更加复杂了。。。说了好多废话,不知道有没有把问题说清楚,总之一句话,神啊!求带走啊!

在中国程序员是青春饭吗?

今年,我也32了 ,为了不给大家误导,咨询了猎头、圈内好友,以及年过35岁的几位老程序员……舍了老脸去揭人家伤疤……希望能给大家以帮助,记得帮我点赞哦。 目录: 你以为的人生 一次又一次的伤害 猎头界的真相 如何应对互联网行业的「中年危机」 一、你以为的人生 刚入行时,拿着傲人的工资,想着好好干,以为我们的人生是这样的: 等真到了那一天,你会发现,你的人生很可能是这样的: ...

程序员请照顾好自己,周末病魔差点一套带走我。

程序员在一个周末的时间,得了重病,差点当场去世,还好及时挽救回来了。

技术大佬:我去,你写的 switch 语句也太老土了吧

昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意。但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:“我擦,小王,你丫写的 switch 语句也太老土了吧!” 来看看小王写的代码吧,看完不要骂我装逼啊。 private static String createPlayer(PlayerTypes p...

和黑客斗争的 6 天!

互联网公司工作,很难避免不和黑客们打交道,我呆过的两家互联网公司,几乎每月每天每分钟都有黑客在公司网站上扫描。有的是寻找 Sql 注入的缺口,有的是寻找线上服务器可能存在的漏洞,大部分都...

上班一个月,后悔当初着急入职的选择了

最近有个老铁,告诉我说,上班一个月,后悔当初着急入职现在公司了。他之前在美图做手机研发,今年美图那边今年也有一波组织优化调整,他是其中一个,在协商离职后,当时捉急找工作上班,因为有房贷供着,不能没有收入来源。所以匆忙选了一家公司,实际上是一个大型外包公司,主要派遣给其他手机厂商做外包项目。**当时承诺待遇还不错,所以就立马入职去上班了。但是后面入职后,发现薪酬待遇这块并不是HR所说那样,那个HR自...

女程序员,为什么比男程序员少???

昨天看到一档综艺节目,讨论了两个话题:(1)中国学生的数学成绩,平均下来看,会比国外好?为什么?(2)男生的数学成绩,平均下来看,会比女生好?为什么?同时,我又联想到了一个技术圈经常讨...

总结了 150 余个神奇网站,你不来瞅瞅吗?

原博客再更新,可能就没了,之后将持续更新本篇博客。

副业收入是我做程序媛的3倍,工作外的B面人生是怎样的?

提到“程序员”,多数人脑海里首先想到的大约是:为人木讷、薪水超高、工作枯燥…… 然而,当离开工作岗位,撕去层层标签,脱下“程序员”这身外套,有的人生动又有趣,马上展现出了完全不同的A/B面人生! 不论是简单的爱好,还是正经的副业,他们都干得同样出色。偶尔,还能和程序员的特质结合,产生奇妙的“化学反应”。 @Charlotte:平日素颜示人,周末美妆博主 大家都以为程序媛也个个不修边幅,但我们也许...

如果你是老板,你会不会踢了这样的员工?

有个好朋友ZS,是技术总监,昨天问我:“有一个老下属,跟了我很多年,做事勤勤恳恳,主动性也很好。但随着公司的发展,他的进步速度,跟不上团队的步伐了,有点...

我入职阿里后,才知道原来简历这么写

私下里,有不少读者问我:“二哥,如何才能写出一份专业的技术简历呢?我总感觉自己写的简历太烂了,所以投了无数份,都石沉大海了。”说实话,我自己好多年没有写过简历了,但我认识的一个同行,他在阿里,给我说了一些他当年写简历的方法论,我感觉太牛逼了,实在是忍不住,就分享了出来,希望能够帮助到你。 01、简历的本质 作为简历的撰写者,你必须要搞清楚一点,简历的本质是什么,它就是为了来销售你的价值主张的。往深...

外包程序员的幸福生活

今天给你们讲述一个外包程序员的幸福生活。男主是Z哥,不是在外包公司上班的那种,是一名自由职业者,接外包项目自己干。接下来讲的都是真人真事。 先给大家介绍一下男主,Z哥,老程序员,是我十多年前的老同事,技术大牛,当过CTO,也创过业。因为我俩都爱好喝酒、踢球,再加上住的距离不算远,所以一直也断断续续的联系着,我对Z哥的状况也有大概了解。 Z哥几年前创业失败,后来他开始干起了外包,利用自己的技术能...

优雅的替换if-else语句

场景 日常开发,if-else语句写的不少吧??当逻辑分支非常多的时候,if-else套了一层又一层,虽然业务功能倒是实现了,但是看起来是真的很不优雅,尤其是对于我这种有强迫症的程序"猿",看到这么多if-else,脑袋瓜子就嗡嗡的,总想着解锁新姿势:干掉过多的if-else!!!本文将介绍三板斧手段: 优先判断条件,条件不满足的,逻辑及时中断返回; 采用策略模式+工厂模式; 结合注解,锦...

深入剖析Springboot启动原理的底层源码,再也不怕面试官问了!

大家现在应该都对Springboot很熟悉,但是你对他的启动原理了解吗?

离职半年了,老东家又发 offer,回不回?

有小伙伴问松哥这个问题,他在上海某公司,在离职了几个月后,前公司的领导联系到他,希望他能够返聘回去,他很纠结要不要回去? 俗话说好马不吃回头草,但是这个小伙伴既然感到纠结了,我觉得至少说明了两个问题:1.曾经的公司还不错;2.现在的日子也不是很如意。否则应该就不会纠结了。 老实说,松哥之前也有过类似的经历,今天就来和小伙伴们聊聊回头草到底吃不吃。 首先一个基本观点,就是离职了也没必要和老东家弄的苦...

2020阿里全球数学大赛:3万名高手、4道题、2天2夜未交卷

阿里巴巴全球数学竞赛( Alibaba Global Mathematics Competition)由马云发起,由中国科学技术协会、阿里巴巴基金会、阿里巴巴达摩院共同举办。大赛不设报名门槛,全世界爱好数学的人都可参与,不论是否出身数学专业、是否投身数学研究。 2020年阿里巴巴达摩院邀请北京大学、剑桥大学、浙江大学等高校的顶尖数学教师组建了出题组。中科院院士、美国艺术与科学院院士、北京国际数学...

男生更看重女生的身材脸蛋,还是思想?

往往,我们看不进去大段大段的逻辑。深刻的哲理,往往短而精悍,一阵见血。问:产品经理挺漂亮的,有点心动,但不知道合不合得来。男生更看重女生的身材脸蛋,还是...

为什么程序员做外包会被瞧不起?

二哥,有个事想询问下您的意见,您觉得应届生值得去外包吗?公司虽然挺大的,中xx,但待遇感觉挺低,马上要报到,挺纠结的。

当HR压你价,说你只值7K,你该怎么回答?

当HR压你价,说你只值7K时,你可以流畅地回答,记住,是流畅,不能犹豫。 礼貌地说:“7K是吗?了解了。嗯~其实我对贵司的面试官印象很好。只不过,现在我的手头上已经有一份11K的offer。来面试,主要也是自己对贵司挺有兴趣的,所以过来看看……”(未完) 这段话主要是陪HR互诈的同时,从公司兴趣,公司职员印象上,都给予对方正面的肯定,既能提升HR的好感度,又能让谈判气氛融洽,为后面的发挥留足空间。...

面试:第十六章:Java中级开发(16k)

HashMap底层实现原理,红黑树,B+树,B树的结构原理 Spring的AOP和IOC是什么?它们常见的使用场景有哪些?Spring事务,事务的属性,传播行为,数据库隔离级别 Spring和SpringMVC,MyBatis以及SpringBoot的注解分别有哪些?SpringMVC的工作原理,SpringBoot框架的优点,MyBatis框架的优点 SpringCould组件有哪些,他们...

面试阿里p7,被按在地上摩擦,鬼知道我经历了什么?

面试阿里p7被问到的问题(当时我只知道第一个):@Conditional是做什么的?@Conditional多个条件是什么逻辑关系?条件判断在什么时候执...

你期望月薪4万,出门右拐,不送,这几个点,你也就是个初级的水平

先来看几个问题通过注解的方式注入依赖对象,介绍一下你知道的几种方式@Autowired和@Resource有何区别说一下@Autowired查找候选者的...

面试了一个 31 岁程序员,让我有所触动,30岁以上的程序员该何去何从?

最近面试了一个31岁8年经验的程序猿,让我有点感慨,大龄程序猿该何去何从。

大三实习生,字节跳动面经分享,已拿Offer

说实话,自己的算法,我一个不会,太难了吧

程序员垃圾简历长什么样?

已经连续五年参加大厂校招、社招的技术面试工作,简历看的不下于万份 这篇文章会用实例告诉你,什么是差的程序员简历! 疫情快要结束了,各个公司也都开始春招了,作为即将红遍大江南北的新晋UP主,那当然要为小伙伴们做点事(手动狗头)。 就在公众号里公开征简历,义务帮大家看,并一一点评。《启舰:春招在即,义务帮大家看看简历吧》 一石激起千层浪,三天收到两百多封简历。 花光了两个星期的所有空闲时...

《经典算法案例》01-08:如何使用质数设计扫雷(Minesweeper)游戏

我们都玩过Windows操作系统中的经典游戏扫雷(Minesweeper),如果把质数当作一颗雷,那么,表格中红色的数字哪些是雷(质数)?您能找出多少个呢?文中用列表的方式罗列了10000以内的自然数、质数(素数),6的倍数等,方便大家观察质数的分布规律及特性,以便对算法求解有指导意义。另外,判断质数是初学算法,理解算法重要性的一个非常好的案例。

《Oracle Java SE编程自学与面试指南》最佳学习路线图(2020最新版)

正确选择比瞎努力更重要!

字节跳动面试官竟然问了我JDBC?

轻松等回家通知

面试官:你连SSO都不懂,就别来面试了

大厂竟然要考我SSO,卧槽。

终于,月薪过5万了!

来看几个问题想不想月薪超过5万?想不想进入公司架构组?想不想成为项目组的负责人?想不想成为spring的高手,超越99%的对手?那么本文内容是你必须要掌握的。本文主要详解bean的生命...

自从喜欢上了B站这12个UP主,我越来越觉得自己是个废柴了!

不怕告诉你,我自从喜欢上了这12个UP主,哔哩哔哩成为了我手机上最耗电的软件,几乎每天都会看,可是吧,看的越多,我就越觉得自己是个废柴,唉,老天不公啊,不信你看看…… 间接性踌躇满志,持续性混吃等死,都是因为你们……但是,自己的学习力在慢慢变强,这是不容忽视的,推荐给你们! 都说B站是个宝,可是有人不会挖啊,没事,今天咱挖好的送你一箩筐,首先啊,我在B站上最喜欢看这个家伙的视频了,为啥 ,咱撇...

立即提问
相关内容推荐