关于Socket与SocketChannel的数据读写问题?

客户端读不到数据??一直处于阻塞状态...问题在服务器端还是客户端?
服务器端发送数据:

 Iterator<SocketChannel> it=clients.iterator();
                    System.out.println(clients.size());
                    while(it.hasNext()){
                        SocketChannel channel=it.next();
                        System.out.println("send message to"+channel.socket().getInetAddress()+":"+content.toString());
                        channel.write(ByteBuffer.allocate(content.length()+2).put((content.toString()+"\r\n").getBytes()));
                    }

客户端读数据:
注意:客户端是使用的Socket,服务器使用的是Channel

 public void run() {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            while (!stop) {
                System.out.println(br.readLine());
                System.out.println("end");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            Resources.close(br);
        }
    }

3个回答

 服务器端的buf的write是需要循环的

还是不对,服务端用非阻塞的方式写入SocketChannel,在客户端能用socket读吗?有没有可行性?

你是对的,原来是我粗心改错了,Socket和Channel是可以相互通信的!

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
求教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(); } ``` ```
Socketchannel写入/读取大量数据问题
我有一个客户端,一个服务端,现在要在服务端截图给客户端,每张图片大概20W字节(200KB)不到 请问socketchannel可以一次性写入这20W字节吗, 就是socketchannel.write(bytebuffer); bytebuffer的limit就是20W不到,这样写入会不会出问题 顺便问问socketchannel的write是异步的吗。。看源码怎么是一个抽象方法
SocketChannel write数据不完整的问题
我用JAVA NIO写的服务端与客户端的Socket连接程序,服务端发送信息,客户端接收信息,服务端发送信息的代码如下图:![图片说明](https://img-ask.csdn.net/upload/201904/02/1554188180_511494.jpg),遇到的问题也在图中,请问各位如何解决,先谢谢
Android Socket使用NIO的基础性问题
在尝试向SocketChannel写入数据时出问题了,每次写入后返回的Size都是0,问题代码如下: ``` SocketChannel socketChannel = null; ByteBuffer sendBuffer = null; ``` 下面这是发送数据的函数中一部分 ``` sendBuffer = ByteBuffer.wrap("hello".getBytes("UTF8")); sendBuffer.flip(); int bufferLength = sendBuffer.array().length; int sendsize = 0; while(sendBuffer.hasRemaining()) { sendsize += socketChannel.write(sendBuffer); } sendBuffer.clear(); ``` 问题1:查看了ByteBuffer.flip() 和 ByteBuffer.clear()的代码发现都是改变它的位置指针,flip是把position 和 limit 都置0,而remaining的值是limit - position,这样一来flip之后remaining不总是等于0吗?我的循环就始终没有执行,但是又在几篇帖子里看到说write之前需要先flip,于是很困惑。 问题2:如果不加while语句,不判断remaining而直接write,发现返回的size还是0,就是说没有数据被写到socketChannel里。 还请大侠指点迷津!
关于nio中的SocketChannel.read()方法原理
<div class="iteye-blog-content-contain" style="font-size: 14px;"> <p>发起请求的代码:</p> <pre name="code" class="java">SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("http://www.test.com", 80));</pre> <p>1)如果请求返回的数据总量是1000byte;这时这1000byte是不是已经返回到客户端了?</p> <p> </p> <p>从SocketChannel中读取数据:</p> <pre name="code" class="java">int bytesRead = socketChannel.read(buf);</pre> <p> </p> <p>2)如果buf大小是1byte,只执行一次read方法后,那剩余的999byte数据在哪里呢?</p> </div>
SocketChannel bind()地址的问题
![图片说明](https://img-ask.csdn.net/upload/201707/14/1500011273_734777.png) 上面的图片是我截取的一部分代码, 是放在while死循环里面的一段.. 因为执行起来很快,不知道循环到多少次的时候开始,每次执行到bind那里的时候,都会出现 如下的异常: ![图片说明](https://img-ask.csdn.net/upload/201707/14/1500011406_563803.png) 上网搜索了下,那个异常主要是因为端口已经被其他线程所绑定,但是, 我这里使用的是socketchannel,是作为客户端,又不是服务器,也就是说绑定的是一个远程的地址(这里使用的是本机回传地址),那么问题来了,难道一个服务器端口只能被一个客户端绑定?咋那么回事?
Socket关闭后,如何清理输出缓冲区来阻止已经在输出缓冲区中的数据发送?
实践发现,当使用socketChannel.close()之后,对于close之前已经写入缓冲区但由于网络原因没有发送成功的数据,在server端网络恢复后,还是能接收到该数据; 求问是否有什么办法能在调用Close之前,将此socketChannel的输出缓冲区中的数据清理掉? 从该博主处得到的:http://blog.csdn.net/Ctrl_qun/article/details/52454380 这些I/O缓冲区特性可整理如下: I/O缓冲区在每个TCP套接字中单独存在; I/O缓冲区在创建套接字时自动生成; 即使关闭套接字也会继续传送输出缓冲区中遗留的数据; 关闭套接字将丢失输入缓冲区中的数据。
SocketChannel发送消息
我在用SocketChannel发送消息时,当第一条消息没有接收到的时候,法第二条就会出现这个错误,请问是什么原因 java.io.IOException: 您的主机中的软件中止了一个已建立的连接。 at sun.nio.ch.SocketDispatcher.read0(Native Method) at sun.nio.ch.SocketDispatcher.read(Unknown Source) at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source) at sun.nio.ch.IOUtil.read(Unknown Source) at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
NIO中的SocketChannel多次write之后 用read如何做到区分多次的数据
例如socketChannel.write(ByteBuffer) buteBuffer的长度可能随时变更,但是接收的时候read方法是以一个固定的长度接收的 发送方 ```java byte[] outData = new byte[2048]; ByteBuffer outByteBuffer = ByteBuffer.wrap(outData); toWriteNrBytes = 获取数据返回一个长度; outByteBuffer.limit(toWriteNrBytes); socketChannel.write(outByteBuffer); ``` 接收方 ```java byte[] inData = new byte[2048]; ByteBuffer inByteBuffer = ByteBuffer.wrap(inData); readNrBytes = socketChannel.read(inByteBuffer); ``` 可是这个readNrBytes并不能实时的到每次写入的长度,请问怎么解决
NIO SocketChannel连接报错
private static void testSocketChannel() throws IOException{ SocketChannel socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress(10086)); while(!socketChannel.finishConnect()){ System.out.println("connecting...."); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("connect success!!"); } 代码如图所以,设想是在连接成功之前,控制台会一直输出connecting....,但运行时只输出2行就报错了。。。。。
关于NIO里面SocketChannel read方法 返回值问题
请问:什么情况下返回0,什么情况下返回-1. TCP/IP不太熟悉,请教各位,希望详细一点。
Android:Socket output is shutdown
``` SocketChannel socketChannel; ByteBuffer sendBuffer; //省略连接部分代码....但确保socketChannel已经和服务器socket连接上了 sendBuffer = ByteBuffer.wrap("hello".getBytes("UTF8")); socketChannel.write(sendBuffer); ``` 最后一行抛出异常java.net.SocketException: Socket output is shutdown
socket 版本问题
一个发送短信的程序 jdk从1.4 升级到1.5后发现速度明显降低 核查发现 是Socket socket = new Socket(hostname,port); 这句在 两个版本下面有明显的区别。 1.4 需要少于1s 而1.5 需要大于5s。 socket创建与建立连接虽然与网络环境有关系 但是不能在同一个环境下 两个版本相差这么多吧 有什么办法能改进一下 提高一下socket创建连接的速度 另外server 端 不允许socket创建长连接 [b]问题补充:[/b] ======================= jdk1.5里有socketchannel,可以这样: InetSocketAddress address = new InetSocketAddress(ip,port); SocketChannel channel = SocketChannel.open(address); 这样就是tcp长链接了。 ========================= 老大 1.4就已经有nio了 SocketChannel 好像在阻塞时间方面不强,所以不敢使用
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; } }
Netty作为socket长链接,在windows部署占用38M左右内存,在linux部署占用1.5G左右内存
不知各位有遇到过这样问题的吗? ![图片说明](https://img-ask.csdn.net/upload/201910/19/1571456018_34605.png) 这是在linux部署直接就这样了 关于启动类我给大家粘一下代码 ``` Thread thread = new Thread(new Runnable() { @Override public void run() { //服务端要建立两个group,一个负责接收客户端的连接,一个负责处理数据传输 //连接处理group EventLoopGroup boss = new NioEventLoopGroup(); //事件处理group EventLoopGroup worker = new NioEventLoopGroup(); ServerBootstrap bootstrap = new ServerBootstrap(); // 绑定处理group bootstrap.group(boss, worker).channel(NioServerSocketChannel.class) //保持连接数 .option(ChannelOption.SO_BACKLOG, 100000) //有数据立即发送 .option(ChannelOption.TCP_NODELAY, true) //保持连接 .childOption(ChannelOption.SO_KEEPALIVE, true) //处理新连接 .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel sc) throws Exception { // 增加任务处理 ChannelPipeline p = sc.pipeline(); p.addLast(new IdleStateHandler(new Integer(new ReadProperties().getUrlValue("read.time.seconds")),0,0)); p.addLast(new ServerIdleStateTrigger()); p.addLast(new Decoder()); p.addLast(new Encoder()); p.addLast(new ServerHandler()); } }).option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT).childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); //绑定端口,同步等待成功 ChannelFuture future; try { future = bootstrap.bind(serverPort).sync(); if (future.isSuccess()) { serverSocketChannel = (ServerSocketChannel) future.channel(); // System.out.println("服务端开启成功"); // 启动定时删除文件的线程 new Thread(new DeleteFile()).start(); } else { // System.out.println("服务端开启失败"); } //等待服务监听端口关闭,就是由于这里会将线程阻塞,导致无法发送信息,所以我这里开了线程 future.channel().closeFuture().sync(); } catch (Exception e) { // e.printStackTrace(); } finally { //优雅地退出,释放线程池资源 boss.shutdownGracefully(); worker.shutdownGracefully(); } } }); ``` handler类继承SimpleChannelInboundHandler
eclipse启动动态项目run on server,tomcat起不来
小白一枚,跪求大神解答,eclipse启动动态项目run on server,tomcat起不来,请问这个情况如何解决 控制台信息如下: 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Server.服务器版本: Apache Tomcat/9.0.19 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Server.构建: Apr 12 2019 14:22:48 UTC 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Server version number: 9.0.19.0 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: OS Name: Windows 7 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: OS.版本: 6.1 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: 结.造: amd64 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Java 环境变量: C:\Program Files\Java\jre1.8.0_73 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: JVM 版本: 1.8.0_73-b02 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: JVM.供应商: Oracle Corporation 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: CATALINA_BASE: E:\workspace\program\.metadata\.plugins\org.eclipse.wst.server.core\tmp1 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: CATALINA_HOME: D:\apache-tomcat-9.0.19 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Dcatalina.base=E:\workspace\program\.metadata\.plugins\org.eclipse.wst.server.core\tmp1 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Dcatalina.home=D:\apache-tomcat-9.0.19 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Dwtp.deploy=E:\workspace\program\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Djava.endorsed.dirs=D:\apache-tomcat-9.0.19\endorsed 十二月 04, 2019 10:34:27 下午 org.apache.catalina.startup.VersionLoggerListener log 信息: Command line argument: -Dfile.encoding=GBK 十二月 04, 2019 10:34:27 下午 org.apache.catalina.core.AprLifecycleListener lifecycleEvent 信息: Loaded APR based Apache Tomcat Native library [1.2.21] using APR version [1.6.5]. 十二月 04, 2019 10:34:27 下午 org.apache.catalina.core.AprLifecycleListener lifecycleEvent 信息: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true]. 十二月 04, 2019 10:34:27 下午 org.apache.catalina.core.AprLifecycleListener lifecycleEvent 信息: APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true] 十二月 04, 2019 10:34:27 下午 org.apache.catalina.core.AprLifecycleListener initializeSSL 信息: OpenSSL successfully initialized [OpenSSL 1.1.1a 20 Nov 2018] 十二月 04, 2019 10:34:28 下午 org.apache.coyote.AbstractProtocol init 信息: 初始化协议处理器 ["http-nio-8080"] 十二月 04, 2019 10:35:10 下午 org.apache.catalina.util.LifecycleBase handleSubClassException 严重: 初始化组件[Connector[HTTP/1.1-8080]]失败。 org.apache.catalina.LifecycleException: Protocol handler initialization failed at org.apache.catalina.connector.Connector.initInternal(Connector.java:983) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:535) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:1059) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136) at org.apache.catalina.startup.Catalina.load(Catalina.java:584) at org.apache.catalina.startup.Catalina.load(Catalina.java:607) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:306) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:491) Caused by: java.io.IOException: Unable to establish loopback connection at sun.nio.ch.PipeImpl$Initializer.run(Unknown Source) at sun.nio.ch.PipeImpl$Initializer.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.nio.ch.PipeImpl.<init>(Unknown Source) at sun.nio.ch.SelectorProviderImpl.openPipe(Unknown Source) at java.nio.channels.Pipe.open(Unknown Source) at sun.nio.ch.WindowsSelectorImpl.<init>(Unknown Source) at sun.nio.ch.WindowsSelectorProvider.openSelector(Unknown Source) at java.nio.channels.Selector.open(Unknown Source) at org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector(NioSelectorPool.java:54) at org.apache.tomcat.util.net.NioSelectorPool.close(NioSelectorPool.java:109) at org.apache.tomcat.util.net.NioEndpoint.unbind(NioEndpoint.java:341) at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1121) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1129) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:557) at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:74) at org.apache.catalina.connector.Connector.initInternal(Connector.java:980) ... 13 more Caused by: java.net.ConnectException: Connection timed out: connect at sun.nio.ch.Net.connect0(Native Method) at sun.nio.ch.Net.connect(Unknown Source) at sun.nio.ch.Net.connect(Unknown Source) at sun.nio.ch.SocketChannelImpl.connect(Unknown Source) at java.nio.channels.SocketChannel.open(Unknown Source) at sun.nio.ch.PipeImpl$Initializer$LoopbackConnector.run(Unknown Source) ... 30 more 十二月 04, 2019 10:35:10 下午 org.apache.coyote.AbstractProtocol init 信息: 初始化协议处理器 ["ajp-nio-8009"] 十二月 04, 2019 10:35:52 下午 org.apache.catalina.util.LifecycleBase handleSubClassException 严重: 初始化组件[Connector[AJP/1.3-8009]]失败。 org.apache.catalina.LifecycleException: Protocol handler initialization failed at org.apache.catalina.connector.Connector.initInternal(Connector.java:983) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:535) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:1059) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:136) at org.apache.catalina.startup.Catalina.load(Catalina.java:584) at org.apache.catalina.startup.Catalina.load(Catalina.java:607) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:306) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:491) Caused by: java.io.IOException: Unable to establish loopback connection at sun.nio.ch.PipeImpl$Initializer.run(Unknown Source) at sun.nio.ch.PipeImpl$Initializer.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at sun.nio.ch.PipeImpl.<init>(Unknown Source) at sun.nio.ch.SelectorProviderImpl.openPipe(Unknown Source) at java.nio.channels.Pipe.open(Unknown Source) at sun.nio.ch.WindowsSelectorImpl.<init>(Unknown Source) at sun.nio.ch.WindowsSelectorProvider.openSelector(Unknown Source) at java.nio.channels.Selector.open(Unknown Source) at org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector(NioSelectorPool.java:54) at org.apache.tomcat.util.net.NioSelectorPool.close(NioSelectorPool.java:109) at org.apache.tomcat.util.net.NioEndpoint.unbind(NioEndpoint.java:341) at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1121) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1129) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:557) at org.apache.catalina.connector.Connector.initInternal(Connector.java:980) ... 13 more Caused by: java.net.ConnectException: Connection timed out: connect at sun.nio.ch.Net.connect0(Native Method) at sun.nio.ch.Net.connect(Unknown Source) at sun.nio.ch.Net.connect(Unknown Source) at sun.nio.ch.SocketChannelImpl.connect(Unknown Source) at java.nio.channels.SocketChannel.open(Unknown Source) at sun.nio.ch.PipeImpl$Initializer$LoopbackConnector.run(Unknown Source) ... 29 more 十二月 04, 2019 10:35:52 下午 org.apache.catalina.startup.Catalina load 信息: 服务器在[85,235]毫秒内初始化 十二月 04, 2019 10:35:52 下午 org.apache.catalina.core.StandardService startInternal 信息: Starting service [Catalina] 十二月 04, 2019 10:35:52 下午 org.apache.catalina.core.StandardEngine startInternal 信息: Starting Servlet engine: [Apache Tomcat/9.0.19] 十二月 04, 2019 10:35:53 下午 org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom 警告: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [557] milliseconds. 十二月 04, 2019 10:35:53 下午 org.apache.jasper.servlet.TldScanner scanJars 信息: 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 十二月 04, 2019 10:35:53 下午 org.apache.catalina.startup.Catalina start 信息: Server startup in [1,428] milliseconds
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 实现socket的异步通信
我在网上也找到一个例子,但是没有客户端,我自己写了一个用ServerSocket连的客户端,但是连接上后不能写也不能读,不知道怎么回事,请高手解决。最好能给一个简单异步编程的例子。 下面是代码: package org.scorpion.scoket; /** * * @author chenjd */ import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.util.HashMap; import java.util.Iterator; import java.util.Set; public class NBServer { int port = 8090; int BUFFERSIZE = 1024; Selector selector = null; ServerSocketChannel serverChannel = null; HashMap clientChannelMap = null;// 用来存放每一个客户连接对应的套接字和通道 public NBServer(int port) { this.clientChannelMap = new HashMap(); this.port = port; } public void initialize() throws IOException { // 初始化,分别实例化一个选择器,一个服务器端可选择通道 this.selector = Selector.open(); this.serverChannel = ServerSocketChannel.open(); this.serverChannel.configureBlocking(false); InetAddress localhost = InetAddress.getLocalHost(); InetSocketAddress isa = new InetSocketAddress(localhost, this.port); this.serverChannel.socket().bind(isa);// 将该套接字绑定到服务器某一可用端口 } // 结束时释放资源 public void finalize() throws IOException { this.serverChannel.close(); this.selector.close(); } // 将读入字节缓冲的信息解码 public String decode(ByteBuffer byteBuffer) throws CharacterCodingException { Charset charset = Charset.forName("ISO-8859-1"); CharsetDecoder decoder = charset.newDecoder(); CharBuffer charBuffer = decoder.decode(byteBuffer); String result = charBuffer.toString(); return result; } // 监听端口,当通道准备好时进行相应操作 public void portListening(String data) throws IOException, InterruptedException { // 服务器端通道注册OP_ACCEPT事件 SelectionKey acceptKey = this.serverChannel.register(this.selector, SelectionKey.OP_ACCEPT); // 当有已注册的事件发生时,select()返回值将大于0 while (acceptKey.selector().select() > 0) { System.out.println("event happened"); // 取得所有已经准备好的所有选择键 Set readyKeys = this.selector.selectedKeys(); // 使用迭代器对选择键进行轮询 Iterator i = readyKeys.iterator(); while (i.hasNext()) { SelectionKey key = (SelectionKey) i.next(); i.remove();// 删除当前将要处理的选择键 if (key.isAcceptable()) {// 如果是有客户端连接请求 System.out.println("more client connect in!"); ServerSocketChannel nextReady = (ServerSocketChannel) key .channel(); // 获取客户端套接字 Socket s = nextReady.accept().socket(); // 设置对应的通道为异步方式并注册感兴趣事件 s.getChannel().configureBlocking(false); SelectionKey readWriteKey = s.getChannel().register( this.selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); // 将注册的事件与该套接字联系起来 readWriteKey.attach(s); // 将当前建立连接的客户端套接字及对应的通道存放在哈希表//clientChannelMap中 this.clientChannelMap.put(s, new ClientChInstance(s .getChannel())); } else if (key.isReadable()) {// 如果是通道读准备好事件 System.out.println("Readable"); // 取得选择键对应的通道和套接字 SelectableChannel nextReady = (SelectableChannel) key .channel(); Socket socket = (Socket) key.attachment(); // 处理该事件,处理方法已封装在类ClientChInstance中 this.readFromChannel(socket.getChannel(), (ClientChInstance) this.clientChannelMap .get(socket)); } else if (key.isWritable()) {// 如果是通道写准备好事件 System.out.println("writeable"); // 取得套接字后处理,方法同上 Socket socket = (Socket) key.attachment(); SocketChannel channel = (SocketChannel) socket.getChannel(); // this.writeToChannel(channel, "This is from server!"); this.writeToChannel(channel, data); } } } } // 对通道的写操作 public void writeToChannel(SocketChannel channel, String message) throws IOException { ByteBuffer buf = ByteBuffer.wrap(message.getBytes()); int nbytes = channel.write(buf); } // 对通道的读操作 public void readFromChannel(SocketChannel channel, ClientChInstance clientInstance) throws IOException, InterruptedException { ByteBuffer byteBuffer = null; try{ byteBuffer = ByteBuffer.allocate(BUFFERSIZE); int nbytes = channel.read(byteBuffer); }catch(Exception e){ clientChannelMap.remove(channel.socket()); channel.close(); e=null; return; } byteBuffer.flip(); String result = this.decode(byteBuffer); // 当客户端发出”@exit”退出命令时,关闭其通道 if (result.indexOf("@exit") >= 0||result.indexOf("q")>=0) { channel.close(); } // else if(result.indexOf("@close") >= 0){//关闭服务 // channel.close(); // this.finalize(); // } else { clientInstance.append(result.toString()); // 读入一行完毕,执行相应操作 if (result.indexOf("\n") >= 0) { System.out.println("client input" + result); clientInstance.execute(); } } } // 该类封装了怎样对客户端的通道进行操作,具体实现可以通过重载execute()方法 public class ClientChInstance { SocketChannel channel; StringBuffer buffer = new StringBuffer(); public ClientChInstance(SocketChannel channel) { this.channel = channel; } public void execute() throws IOException { String message = "This is response after reading from channel!"; writeToChannel(this.channel, message); buffer = new StringBuffer(); } // 当一行没有结束时,将当前字窜置于缓冲尾 public void append(String values) { buffer.append(values); } } // 主程序 public static void main(String[] args) { NBServer nbServer = new NBServer(8090); try { nbServer.initialize(); } catch (Exception e) { e.printStackTrace(); System.exit(-1); } try { nbServer.portListening("This is from server!"); } catch (Exception e) { e.printStackTrace(); } } } 我写的客户端: package org.scorpion.scoket; import java.io.OutputStream; import java.net.Socket; public class TCPClient { public static void main(String[] args) throws Exception { Socket s = new Socket("172.22.71.146", 8000); OutputStream os = s.getOutputStream(); byte[] by="ksfsksjfklsdjflsdj".getBytes(); os.write(by); s.close(); } }
Java与c++进行Socket通信问题--求帮助
服务器端是C++开发的,Java开发客户端。客户端发送给服务器端的信息服务器那边可以收到,服务器也发出了响应,但是客户端一直阻塞,无法获取数据。不知道大伙能不能分享下这方面的经验。如果有样例程序更好。 在此先行谢过。 [code="java"] import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.SocketChannel; public class WhyNotWork { /** * @param args * @throws IOException * @throws UnknownHostException * @throws IOException */ public static void main(String[] args) throws UnknownHostException { String sendString = Header.get() + "hello "; Socket socket = null; try { socket = new Socket("192.168.10.3", 5555); } catch (IOException e) { e.printStackTrace(); } if (socket.isConnected()) { System.out.println("is connected"); } else { return; } PrintWriter writer = null; BufferedReader reader = null; try { writer = new PrintWriter(socket.getOutputStream()); reader = new BufferedReader(new InputStreamReader(socket .getInputStream())); writer.println(sendString.getBytes()); writer.flush(); char[] buffer = new char[1024]; while (reader.read(buffer) != -1) { System.out.println(new String(buffer)); } } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (writer != null) { writer.close(); } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } } [/code]
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、PDF搜索网站推荐 对于大部
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 顺便拉下票,我在参加csdn博客之星竞选,欢迎投票支持,每个QQ或者微信每天都可以投5票,扫二维码即可,http://m234140.nofollow.ax.
Vue + Spring Boot 项目实战(十四):用户认证方案与完善的访问拦截
本篇文章主要讲解 token、session 等用户认证方案的区别并分析常见误区,以及如何通过前后端的配合实现完善的访问拦截,为下一步权限控制的实现打下基础。
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入  假设现有4个人
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 欢迎 改进 留言。 演示地点跳到演示地点 html代码如下`&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;music&lt;/title&gt; &lt;meta charset="utf-8"&gt
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。 1. for - else 什么?不是 if 和 else 才
数据库优化 - SQL优化
前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优。但是一些“不好”的SQL也会导致数据库查询变慢,影响业务流程。本文从SQL角度进行数据库优化,提升SQL运行效率。 判断问题SQL 判断SQL是否有问题时可以通过两个表象进行判断: 系统级别表象 CPU消耗严重 IO等待严重 页面响应时间过长
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 c/c++ 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7
通俗易懂地给女朋友讲:线程池的内部原理
餐厅的约会 餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”我楞了一下,心里想女朋友今天是怎么了,怎么突然问出这么专业的问题,但做为一个专业人士在女朋友面前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!” 大龄程序员老王 老王是一个已经北漂十多年的程序员,岁数大了,加班加不动了,升迁也无望,于是拿着手里
经典算法(5)杨辉三角
写在前面: 我是 扬帆向海,这个昵称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。 这博客是对自己学习的一点点总结及记录,如果您对 Java、算法 感兴趣,可以关注我的动态,我们一起学习。 用知识改变命运,让我们的家人过上更好的生活。 目录一、杨辉三角的介绍二、杨辉三角的算法思想三、代码实现1.第一种写法2.第二种写法 一、杨辉三角的介绍 百度
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹
面试官:你连RESTful都不知道我怎么敢要你?
面试官:了解RESTful吗? 我:听说过。 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是RESTful挺好的,还是自我感觉挺好的 我:都挺好的。 面试官:… 把门关上。 我:… 要干嘛?先关上再说。 面试官:我说出去把门关上。 我:what ?,夺门而去 文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看
SQL-小白最佳入门sql查询一
一 说明 如果是初学者,建议去网上寻找安装Mysql的文章安装,以及使用navicat连接数据库,以后的示例基本是使用mysql数据库管理系统; 二 准备前提 需要建立一张学生表,列分别是id,名称,年龄,学生信息;本示例中文章篇幅原因SQL注释略; 建表语句: CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // dosho
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,
程序员:我终于知道post和get的区别
IT界知名的程序员曾说:对于那些月薪三万以下,自称IT工程师的码农们,其实我们从来没有把他们归为我们IT工程师的队伍。他们虽然总是以IT工程师自居,但只是他们一厢情愿罢了。 此话一出,不知激起了多少(码农)程序员的愤怒,却又无可奈何,于是码农问程序员。 码农:你知道get和post请求到底有什么区别? 程序员:你看这篇就知道了。 码农:你月薪三万了? 程序员:嗯。 码农:你是怎么做到的? 程序员:
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU
加快推动区块链技术和产业创新发展,2019可信区块链峰会在京召开
      11月8日,由中国信息通信研究院、中国通信标准化协会、中国互联网协会、可信区块链推进计划联合主办,科技行者协办的2019可信区块链峰会将在北京悠唐皇冠假日酒店开幕。   区块链技术被认为是继蒸汽机、电力、互联网之后,下一代颠覆性的核心技术。如果说蒸汽机释放了人类的生产力,电力解决了人类基本的生活需求,互联网彻底改变了信息传递的方式,区块链作为构造信任的技术有重要的价值。   1
程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
第一幕:缘起 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员…… 996程序员做的梦: 第一场:团队招募 为了应对地府管理危机,阎王打算找“人”开发一套地府后台管理系统,于是就在地府总经办群中发了项目需求。 话说还是中国电信的信号好,地府都是满格,哈哈!!! 经常会有外行朋友问:看某网站做的不错,功能也简单,你帮忙做一下? 而这次,面对这样的需求,这个程序员
Android 9.0系统新特性,对刘海屏设备进行适配
其实Android 9.0系统已经是去年推出的“老”系统了,这个系统中新增了一个比较重要的特性,就是对刘海屏设备进行了支持。一直以来我也都有打算针对这个新特性好好地写一篇文章,但是为什么直到拖到了Android 10.0系统都发布了才开始写这篇文章呢?当然,一是因为我这段时间确实比较忙,今年几乎绝大部分的业余时间都放到写新书上了。但是最主要的原因并不是这个,而是因为刘海屏设备的适配存在一定的特殊性
网易云6亿用户音乐推荐算法
网易云音乐是音乐爱好者的集聚地,云音乐推荐系统致力于通过 AI 算法的落地,实现用户千人千面的个性化推荐,为用户带来不一样的听歌体验。 本次分享重点介绍 AI 算法在音乐推荐中的应用实践,以及在算法落地过程中遇到的挑战和解决方案。 将从如下两个部分展开: AI 算法在音乐推荐中的应用 音乐场景下的 AI 思考 从 2013 年 4 月正式上线至今,网易云音乐平台持续提供着:乐屏社区、UGC
【技巧总结】位运算装逼指南
位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。 判断奇偶数 判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下
日均350000亿接入量,腾讯TubeMQ性能超过Kafka
整理 | 夕颜出品 | AI科技大本营(ID:rgznai100) 【导读】近日,腾讯开源动作不断,相继开源了分布式消息中间件TubeMQ,基于最主流的 OpenJDK8开发的
8年经验面试官详解 Java 面试秘诀
    作者 | 胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给出若干准备简历和准备面试的建议。   Java程序员准备和投递简历的实
面试官如何考察你的思维方式?
1.两种思维方式在求职面试中,经常会考察这种问题:北京有多少量特斯拉汽车? 某胡同口的煎饼摊一年能卖出多少个煎饼? 深圳有多少个产品经理? 一辆公交车里能装下多少个乒乓球? 一
相关热词 如何提升c#开发能力 矩阵乘法c# c#调用谷歌浏览器 c# 去空格去转义符 c#用户登录窗体代码 c# 流 c# linux 可视化 c# mvc 返回图片 c# 像素空间 c# 日期 最后一天
立即提问