Java BIO socket
package org.rx.socks; import lombok.extern.slf4j.Slf4j;
import org.rx.core.LogWriter;
import org.rx.core.NQuery;
import org.rx.beans.DateTime; import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket; import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque; import static org.rx.core.Contract.require; @Slf4j
public final class SocketPool extends Traceable implements AutoCloseable {
public static final class PooledSocket implements AutoCloseable {
private final SocketPool owner;
private DateTime lastActive;
public final Socket socket; public boolean isConnected() {
return !owner.isClosed() && !socket.isClosed() && socket.isConnected();
} public DateTime getLastActive() {
return lastActive;
} public void setLastActive(DateTime lastActive) {
this.lastActive = lastActive;
} private PooledSocket(SocketPool owner, Socket socket) {
this.owner = owner;
this.socket = socket;
lastActive = DateTime.utcNow();
} @Override
public void close() {
owner.returnSocket(this);
}
} public static final SocketPool Pool = new SocketPool();
private static final int DefaultConnectTimeout = 30000;
private static final int DefaultMaxIdleMillis = 120000;
private static final int DefaultMaxSocketsCount = 64;
private final ConcurrentHashMap<InetSocketAddress, ConcurrentLinkedDeque<PooledSocket>> pool;
private volatile int connectTimeout;
private volatile int maxIdleMillis;
private volatile int maxSocketsCount;
private final Timer timer;
private volatile boolean isTimerRun; public int getConnectTimeout() {
return connectTimeout;
} public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
} public int getMaxIdleMillis() {
return maxIdleMillis;
} public void setMaxIdleMillis(int maxIdleMillis) {
if (maxIdleMillis <= 0) {
maxIdleMillis = DefaultMaxIdleMillis;
}
this.maxIdleMillis = maxIdleMillis;
} public int getMaxSocketsCount() {
return maxSocketsCount;
} public void setMaxSocketsCount(int maxSocketsCount) {
if (maxSocketsCount < 0) {
maxSocketsCount = 0;
}
this.maxSocketsCount = maxSocketsCount;
} private SocketPool() {
pool = new ConcurrentHashMap<>();
connectTimeout = DefaultConnectTimeout;
maxIdleMillis = DefaultMaxIdleMillis;
maxSocketsCount = DefaultMaxSocketsCount;
String n = "SocketPool";
timer = new Timer(n, true);
LogWriter tracer = new LogWriter();
tracer.setPrefix(n + " ");
tracer.info("started..");
setTracer(tracer);
} @Override
protected void freeObjects() {
clear();
} private void runTimer() {
if (isTimerRun) {
return;
}
synchronized (timer) {
if (isTimerRun) {
return;
} long period = 90000;
timer.schedule(new TimerTask() {
@Override
public void run() {
clearIdleSockets();
}
}, period, period);
isTimerRun = true;
}
getTracer().info("runTimer..");
} private void clearIdleSockets() {
for (Map.Entry<InetSocketAddress, ConcurrentLinkedDeque<PooledSocket>> entry : NQuery.of(pool.entrySet())) {
ConcurrentLinkedDeque<PooledSocket> sockets = entry.getValue();
if (sockets == null) {
continue;
} for (PooledSocket socket : NQuery.of(sockets)) {
if (!socket.isConnected()
|| DateTime.utcNow().subtract(socket.getLastActive()).getTotalMilliseconds() >= maxIdleMillis) {
sockets.remove(socket);
getTracer().info("clear idle socket[local=%s, remote=%s]..",
Sockets.getId(socket.socket, false), Sockets.getId(socket.socket, true));
}
}
if (sockets.isEmpty()) {
pool.remove(entry.getKey());
}
}
if (pool.size() == 0) {
stopTimer();
}
} private void stopTimer() {
synchronized (timer) {
timer.cancel();
timer.purge();
isTimerRun = false;
}
getTracer().info("stopTimer..");
} private ConcurrentLinkedDeque<PooledSocket> getSockets(InetSocketAddress remoteAddr) {
ConcurrentLinkedDeque<PooledSocket> sockets = pool.get(remoteAddr);
if (sockets == null) {
pool.put(remoteAddr, sockets = new ConcurrentLinkedDeque<>());
runTimer();
}
return sockets;
} public PooledSocket borrowSocket(InetSocketAddress remoteAddr) {
checkNotClosed();
require(remoteAddr); boolean isExisted = true;
ConcurrentLinkedDeque<PooledSocket> sockets = getSockets(remoteAddr);
PooledSocket pooledSocket;
if ((pooledSocket = sockets.pollFirst()) == null) {
Socket sock = new Socket();
try {
sock.connect(remoteAddr, connectTimeout);
} catch (IOException ex) {
throw new SocketException(remoteAddr, ex);
}
pooledSocket = new PooledSocket(this, sock);
isExisted = false;
}
if (!pooledSocket.isConnected()) {
if (isExisted) {
sockets.remove(pooledSocket);
}
return borrowSocket(remoteAddr);
}
Socket sock = pooledSocket.socket;
getTracer().info("borrow %s socket[local=%s, remote=%s]..", isExisted ? "existed" : "new",
Sockets.getId(sock, false), Sockets.getId(sock, true));
return pooledSocket;
} public void returnSocket(PooledSocket pooledSocket) {
checkNotClosed();
require(pooledSocket); String action = "return";
try {
if (!pooledSocket.isConnected()) {
action = "discard closed";
return;
}
pooledSocket.setLastActive(DateTime.utcNow());
ConcurrentLinkedDeque<PooledSocket> sockets = getSockets(
(InetSocketAddress) pooledSocket.socket.getRemoteSocketAddress());
if (sockets.size() >= maxSocketsCount || sockets.contains(pooledSocket)) {
action = "discard contains";
return;
} sockets.addFirst(pooledSocket);
} finally {
Socket sock = pooledSocket.socket;
getTracer().info("%s socket[local=%s, remote=%s]..", action, Sockets.getId(sock, false),
Sockets.getId(sock, true));
}
} public void clear() {
checkNotClosed(); for (Socket socket : NQuery.of(pool.values()).selectMany(p -> p).select(p -> p.socket)) {
try {
getTracer().info("clear socket[local=%s, remote=%s]..", Sockets.getId(socket, false),
Sockets.getId(socket, true));
Sockets.close(socket);
} catch (Exception ex) {
log.error("SocketPool clear", ex);
}
}
pool.clear();
}
}
package org.rx.socks; import org.rx.core.Disposable;
import org.rx.core.LogWriter; import static org.rx.core.Contract.isNull; public abstract class Traceable extends Disposable {
private LogWriter tracer; public LogWriter getTracer() {
return tracer;
} public synchronized void setTracer(LogWriter tracer) {
this.tracer = isNull(tracer, new LogWriter());
}
}
package org.rx.socks; import lombok.extern.slf4j.Slf4j;
import org.rx.beans.$;
import org.rx.beans.Tuple;
import org.rx.util.BufferSegment;
import org.rx.util.BytesSegment;
import org.rx.core.*;
import org.rx.core.AsyncTask;
import org.rx.io.MemoryStream; import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import static org.rx.beans.$.$;
import static org.rx.core.Contract.isNull;
import static org.rx.core.Contract.require; @Slf4j
public class DirectSocket extends Traceable implements AutoCloseable {
@FunctionalInterface
public interface SocketSupplier {
Tuple<AutoCloseable, Socket> get(MemoryStream pack);
} private static class ClientItem {
private final DirectSocket owner;
private final BufferSegment segment;
public final NetworkStream stream;
public final AutoCloseable toSock;
public final NetworkStream toStream; public ClientItem(Socket client, DirectSocket owner) {
this.owner = owner;
segment = new BufferSegment(Contract.config.getDefaultBufferSize(), 2);
try {
stream = new NetworkStream(client, segment.alloc());
if (owner.directAddress != null) {
SocketPool.PooledSocket pooledSocket = App.retry(owner.connectRetryCount,
p -> SocketPool.Pool.borrowSocket(p.directAddress), owner);
toSock = pooledSocket;
toStream = new NetworkStream(pooledSocket.socket, segment.alloc(), false);
return;
}
if (owner.directSupplier != null) {
MemoryStream firstPack = new MemoryStream(32, true);
BytesSegment buffer = stream.getSegment();
int read;
while ((read = stream.readSegment()) > 0) {
System.out.println("----:" + Bytes.toString(buffer.array, buffer.offset, read));
firstPack.write(buffer.array, buffer.offset, read);
Tuple<AutoCloseable, Socket> toSocks;
if ((toSocks = owner.directSupplier.get(firstPack)) != null) {
toSock = toSocks.left;
firstPack.writeTo(toStream = new NetworkStream(toSocks.right, segment.alloc(), false));
return;
}
}
log.info("DirectSocket ClientState directSupplier read: {}\ncontent: {}", read,
Bytes.toString(firstPack.toArray(), 0, firstPack.getLength()));
}
} catch (IOException ex) {
throw new SocketException((InetSocketAddress) client.getLocalSocketAddress(), ex);
}
throw new SocketException((InetSocketAddress) client.getLocalSocketAddress(),
"DirectSocket directSupplier error");
} public void closeSocket() {
owner.getTracer().info("client close socket[%s->%s]..", Sockets.getId(stream.getSocket(), false),
Sockets.getId(stream.getSocket(), true));
owner.clients.remove(this);
stream.close();
} public void closeToSocket(boolean pooling) {
owner.getTracer().info("client %s socket[%s->%s]..", pooling ? "pooling" : "close",
Sockets.getId(toStream.getSocket(), false), Sockets.getId(toStream.getSocket(), true));
if (pooling) {
try {
toSock.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
Sockets.close(toStream.getSocket());
}
}
} public static final SocketSupplier HttpSupplier = pack -> {
String line = Bytes.readLine(pack.getBuffer());
if (line == null) {
return null;
}
InetSocketAddress authority;
try {
authority = Sockets.parseEndpoint(
new URL(line.split(" ")[1])
.getAuthority());
} catch (MalformedURLException ex) {
throw SystemException.wrap(ex);
}
SocketPool.PooledSocket pooledSocket = App.retry(2,
p -> SocketPool.Pool.borrowSocket(p),
authority);
return Tuple.of(pooledSocket, pooledSocket.socket);
};
private static final int DefaultBacklog = 128;
private static final int DefaultConnectRetryCount = 4;
private final ServerSocket server;
private final List<ClientItem> clients;
private volatile int connectRetryCount;
private InetSocketAddress directAddress;
private SocketSupplier directSupplier; @Override
public boolean isClosed() {
return !(!super.isClosed() && !server.isClosed());
} public InetSocketAddress getLocalAddress() {
return (InetSocketAddress) server.getLocalSocketAddress();
} public NQuery<Tuple<Socket, Socket>> getClients() {
return NQuery.of(clients).select(p -> Tuple.of(p.stream.getSocket(), p.toStream.getSocket()));
} public int getConnectRetryCount() {
return connectRetryCount;
} public void setConnectRetryCount(int connectRetryCount) {
if (connectRetryCount <= 0) {
connectRetryCount = 1;
}
this.connectRetryCount = connectRetryCount;
} public DirectSocket(int listenPort, InetSocketAddress directAddr) {
this(new InetSocketAddress(Sockets.AnyAddress, listenPort), directAddr, null);
} public DirectSocket(InetSocketAddress listenAddr, InetSocketAddress directAddr, SocketSupplier directSupplier) {
require(listenAddr);
require(this, directAddr != null || directSupplier != null); try {
server = new ServerSocket();
server.setReuseAddress(true);
server.bind(listenAddr, DefaultBacklog);
} catch (IOException ex) {
throw new SocketException(listenAddr, ex);
}
directAddress = directAddr;
this.directSupplier = directSupplier;
clients = Collections.synchronizedList(new ArrayList<>());
connectRetryCount = DefaultConnectRetryCount;
String taskName = String.format("DirectSocket[%s->%s]", listenAddr, isNull(directAddress, "autoAddress"));
LogWriter tracer = new LogWriter();
tracer.setPrefix(taskName + " ");
setTracer(tracer);
AsyncTask.TaskFactory.run(() -> {
getTracer().info("start..");
while (!isClosed()) {
try {
ClientItem client = new ClientItem(server.accept(), this);
clients.add(client);
onReceive(client, taskName);
} catch (IOException ex) {
log.error(taskName, ex);
}
}
close();
}, taskName);
} @Override
protected void freeObjects() {
try {
for (ClientItem client : NQuery.of(clients)) {
client.closeSocket();
}
clients.clear();
server.close();
} catch (IOException ex) {
log.error("DirectSocket close", ex);
}
getTracer().info("stop..");
} private void onReceive(ClientItem client, String taskName) {
AsyncTask.TaskFactory.run(() -> {
try {
int recv = client.stream.directTo(client.toStream, (p1, p2) -> {
getTracer().info("sent %s bytes from %s to %s..", p2,
Sockets.getId(client.stream.getSocket(), true),
Sockets.getId(client.toStream.getSocket(), false));
return true;
});
getTracer().info("socket[%s->%s] closing with %s", Sockets.getId(client.stream.getSocket(), false),
Sockets.getId(client.stream.getSocket(), true), recv);
} catch (SystemException ex) {
$<java.net.SocketException> out = $();
if (ex.tryGet(out, java.net.SocketException.class)) {
if (out.v.getMessage().contains("Socket closed")) {
//ignore
log.debug("DirectTo ignore socket closed");
return;
}
}
throw ex;
} finally {
client.closeSocket();
}
}, String.format("%s[networkStream]", taskName));
AsyncTask.TaskFactory.run(() -> {
int recv = NetworkStream.StreamEOF;
try {
recv = client.toStream.directTo(client.stream, (p1, p2) -> {
getTracer().info("recv %s bytes from %s to %s..", p2,
Sockets.getId(client.toStream.getSocket(), false),
Sockets.getId(client.stream.getSocket(), true));
return true;
});
getTracer().info("socket[%s->%s] closing with %s", Sockets.getId(client.toStream.getSocket(), false),
Sockets.getId(client.toStream.getSocket(), true), recv);
} catch (SystemException ex) {
$<java.net.SocketException> out = $();
if (ex.tryGet(out, java.net.SocketException.class)) {
if (out.v.getMessage().contains("Socket closed")) {
//ignore
log.debug("DirectTo ignore socket closed");
return;
}
}
throw ex;
} finally {
client.closeToSocket(recv == NetworkStream.CannotWrite);
}
}, String.format("%s[toNetworkStream]", taskName));
}
}
package org.rx.socks; import lombok.extern.slf4j.Slf4j;
import org.rx.util.BytesSegment;
import org.rx.io.IOStream; import java.io.IOException;
import java.net.Socket; import static org.rx.core.Contract.require;
import static org.rx.socks.Sockets.shutdown; @Slf4j
public final class NetworkStream extends IOStream {
@FunctionalInterface
public interface DirectPredicate {
boolean test(BytesSegment buffer, int count);
} public static final int SocketEOF = 0;
public static final int StreamEOF = -1;
public static final int CannotWrite = -2;
private final boolean ownsSocket;
private final Socket socket;
private final BytesSegment segment; public boolean isConnected() {
return !isClosed() && !socket.isClosed() && socket.isConnected();
} @Override
public boolean canRead() {
return super.canRead() && checkSocket(socket, false);
} @Override
public boolean canWrite() {
return super.canWrite() && checkSocket(socket, true);
} private static boolean checkSocket(Socket sock, boolean isWrite) {
return !sock.isClosed() && sock.isConnected() && !(isWrite ? sock.isOutputShutdown() : sock.isInputShutdown());
} public Socket getSocket() {
return socket;
} public BytesSegment getSegment() {
return segment;
} public NetworkStream(Socket socket, BytesSegment segment) throws IOException {
this(socket, segment, true);
} public NetworkStream(Socket socket, BytesSegment segment, boolean ownsSocket) throws IOException {
super(socket.getInputStream(), socket.getOutputStream()); this.ownsSocket = ownsSocket;
this.socket = socket;
this.segment = segment;
} @Override
protected void freeObjects() {
try {
log.info("NetworkStream freeObjects ownsSocket={} socket[{}][closed={}]", ownsSocket,
Sockets.getId(socket, false), socket.isClosed());
if (ownsSocket) {
//super.freeObjects(); Ignore this!!
Sockets.close(socket, 1);
}
} finally {
segment.close();
}
} int readSegment() {
return read(segment.array, segment.offset, segment.count);
} void writeSegment(int count) {
write(segment.array, segment.offset, count);
} public int directTo(NetworkStream to, DirectPredicate onEach) {
checkNotClosed();
require(to); int recv = StreamEOF;
while (canRead() && (recv = read(segment.array, segment.offset, segment.count)) >= -1) {
if (recv <= 0) {
if (ownsSocket) {
log.debug("DirectTo read {} flag and shutdown send", recv);
shutdown(socket, 1);
}
break;
} if (!to.canWrite()) {
log.debug("DirectTo read {} bytes and can't write", recv);
recv = CannotWrite;
break;
}
to.write(segment.array, segment.offset, recv); if (onEach != null && !onEach.test(segment, recv)) {
recv = StreamEOF;
break;
}
}
if (to.canWrite()) {
to.flush();
}
return recv;
}
}
package org.rx.socks; import org.rx.core.SystemException; import java.net.InetSocketAddress; public class SocketException extends SystemException {
private InetSocketAddress localAddress; public InetSocketAddress getLocalAddress() {
return localAddress;
} public SocketException(InetSocketAddress localAddress, Exception ex) {
super(ex);
this.localAddress = localAddress;
} public SocketException(InetSocketAddress localAddress, String msg) {
super(msg);
this.localAddress = localAddress;
}
}
package org.rx.socks; import java.io.IOException;
import java.net.*; import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.ServerChannel;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.rx.core.Strings;
import org.rx.core.SystemException;
import org.rx.core.WeakCache;
import org.springframework.util.CollectionUtils; import java.util.List;
import java.util.Properties;
import java.util.function.Function; import static org.rx.core.Contract.require;
import static org.rx.core.Contract.values; public final class Sockets {
public static final InetAddress LocalAddress, AnyAddress; static {
LocalAddress = InetAddress.getLoopbackAddress();
try {
AnyAddress = InetAddress.getByName("0.0.0.0");
} catch (Exception ex) {
throw SystemException.wrap(ex);
}
} public InetAddress[] getAddresses(String host) {
return (InetAddress[]) WeakCache.getOrStore("Sockets.getAddresses", values(host), p -> {
try {
return InetAddress.getAllByName(host);
} catch (UnknownHostException ex) {
throw SystemException.wrap(ex);
}
});
} public static InetSocketAddress getAnyEndpoint(int port) {
return new InetSocketAddress(AnyAddress, port);
} public static InetSocketAddress parseEndpoint(String endpoint) {
require(endpoint); String[] arr = Strings.split(endpoint, ":", 2);
return new InetSocketAddress(arr[0], Integer.parseInt(arr[1]));
} public static void writeAndFlush(Channel channel, Object... packs) {
require(channel); channel.eventLoop().execute(() -> {
for (Object pack : packs) {
channel.write(pack);
}
channel.flush();
});
} public static EventLoopGroup bossEventLoop() {
return eventLoopGroup(1);
} public static EventLoopGroup workEventLoop() {
return eventLoopGroup(0);
} public static EventLoopGroup eventLoopGroup(int threadAmount) {
return Epoll.isAvailable() ? new EpollEventLoopGroup(threadAmount) : new NioEventLoopGroup(threadAmount); //NioEventLoopGroup(0, TaskFactory.getExecutor());
} public static Bootstrap bootstrap() {
return bootstrap(getChannelClass());
} public static Bootstrap bootstrap(Class<? extends Channel> channelClass) {
require(channelClass); return new Bootstrap().group(channelClass.getName().startsWith("Epoll") ? new EpollEventLoopGroup() : new NioEventLoopGroup()).channel(channelClass);
} public static Bootstrap bootstrap(Channel channel) {
require(channel); return new Bootstrap().group(channel.eventLoop()).channel(channel.getClass());
} public static Class<? extends ServerChannel> getServerChannelClass() {
return Epoll.isAvailable() ? EpollServerSocketChannel.class : NioServerSocketChannel.class;
} public static Class<? extends Channel> getChannelClass() {
return Epoll.isAvailable() ? EpollSocketChannel.class : NioSocketChannel.class;
} public static void closeOnFlushed(Channel channel) {
require(channel); if (!channel.isActive()) {
return;
}
channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
} public static void close(Socket socket) {
close(socket, 1 | 2);
} public static void close(Socket socket, int flags) {
require(socket); if (!socket.isClosed()) {
shutdown(socket, flags);
try {
socket.setSoLinger(true, 2);
socket.close();
} catch (IOException ex) {
throw SystemException.wrap(ex);
}
}
} /**
* @param socket
* @param flags Send=1, Receive=2
*/
public static void shutdown(Socket socket, int flags) {
require(socket); if (!socket.isClosed() && socket.isConnected()) {
try {
if ((flags & 1) == 1 && !socket.isOutputShutdown()) {
socket.shutdownOutput();
}
if ((flags & 2) == 2 && !socket.isInputShutdown()) {
socket.shutdownInput();
}
} catch (IOException ex) {
throw SystemException.wrap(ex);
}
}
} public static String getId(Socket sock, boolean isRemote) {
require(sock); InetSocketAddress addr = (InetSocketAddress) (isRemote ? sock.getRemoteSocketAddress()
: sock.getLocalSocketAddress());
return addr.getHostString() + ":" + addr.getPort();
} public static <T> T httpProxyInvoke(String proxyAddr, Function<String, T> func) {
setHttpProxy(proxyAddr);
try {
return func.apply(proxyAddr);
} finally {
clearHttpProxy();
}
} public static void setHttpProxy(String proxyAddr) {
setHttpProxy(proxyAddr, null, null, null);
} public static void setHttpProxy(String proxyAddr, List<String> nonProxyHosts, String userName, String password) {
InetSocketAddress ipe = parseEndpoint(proxyAddr);
Properties prop = System.getProperties();
prop.setProperty("http.proxyHost", ipe.getAddress().getHostAddress());
prop.setProperty("http.proxyPort", String.valueOf(ipe.getPort()));
prop.setProperty("https.proxyHost", ipe.getAddress().getHostAddress());
prop.setProperty("https.proxyPort", String.valueOf(ipe.getPort()));
if (!CollectionUtils.isEmpty(nonProxyHosts)) {
//如"localhost|192.168.0.*"
prop.setProperty("http.nonProxyHosts", String.join("|", nonProxyHosts));
}
if (userName != null && password != null) {
Authenticator.setDefault(new UserAuthenticator(userName, password));
}
} public static void clearHttpProxy() {
System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
System.clearProperty("http.nonProxyHosts");
} static class UserAuthenticator extends Authenticator {
private String userName;
private String password; public UserAuthenticator(String userName, String password) {
this.userName = userName;
this.password = password;
} protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password.toCharArray());
}
}
}
Java BIO socket的更多相关文章
- JAVA BIO与NIO、AIO的区别
IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...
- java bio 之聊天室
最近在复习java io相关知识 ,发现很多细节之前没学习到位,原理也没吃透,只能感叹本人愚钝. 复习到bio,顺手写了个简单的聊天室功能,并和大家分享下. 服务端: package io.QQ聊天室 ...
- Java BIO及实现
发现日常学习过的知识不久就会遗忘,在此只是整理并记录一下学习笔记,做个回忆,并方便以后查阅,若有错误,欢迎指正 网络模型:TCP/IP网络模型是从OSI七层模型中演化来的,osi模型分为物理层,数据链 ...
- 3. 彤哥说netty系列之Java BIO NIO AIO进化史
你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...
- [转帖]JAVA BIO与NIO、AIO的区别(这个容易理解)
JAVA BIO与NIO.AIO的区别(这个容易理解) https://blog.csdn.net/ty497122758/article/details/78979302 2018-01-05 11 ...
- Java BIO NIO 与 AIO
回顾 上一章我们介绍了操作系统层面的 IO 模型. 阻塞 IO 模型. 非阻塞 IO 模型. IO 复用模型. 信号驱动 IO 模型(用的不多,知道个概念就行). 异步 IO 模型. 并且介绍了 IO ...
- 【转】JAVA BIO与NIO、AIO的区别
Java中IO的模型分为三种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. BIO[同步阻塞] 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个Ser ...
- Java BIO、NIO与AIO的介绍(学习过程)
Java BIO.NIO与AIO的介绍 因为netty是一个NIO的框架,所以在学习netty的过程中,开始之前.针对于BIO,NIO,AIO进行一个完整的学习. 学习资源分享: Netty学习:ht ...
- Netty之JAVA BIO模型
一.JAVA BIO模型 1.I/O模型 I/O 模型简单的理解:就是用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的性能 Java 共支持 3 种网络编程模型/IO 模式:BIO.NI ...
随机推荐
- (66) c# async await
1.使用 async await 2.返回值 static void Main(string[] args) { Program p = new Program(); Console.WriteLin ...
- jmeter添加自定义扩展函数之Strng---base64解密
1,打开eclipse,新建maven工程,在pom中引用jmeter核心jar包,具体请看---https://www.cnblogs.com/guanyf/p/10863033.html---,这 ...
- Linux ftp安装
ftp安装部分,操作步骤如下: 可以使用yum命令直接安装ftp # yum install vsftpd ftp服务的开启与关闭命令: 开启:# /bin/systemctl start vsftp ...
- day 84 Xadmin组件之构建表单数据
一 .先设置一些相关配置 1. 创建数据库模型. 在app01 下创建 from django.db import models # Create your models here. class Au ...
- Java导入
导入(import)声明用于将任何类型导入编译单元.导入(import)声明出现在包声明之后,第一个类型声明之前. 有两种类型的导入声明: 单类型导入声明 按需导入声明 单类型导入声明 单类型导入声明 ...
- Eclipse插件pydev编辑.py文件时报错:unresolved import error.解决办法
在同一个包中import还报unresolved import error.感觉很奇怪,原来需要把当前的包也要添加到System libs中
- 详解 CSS 绝对定位
基本定义和用法 在 CSS 中,position 属性指定一个元素(静态的,相对的,绝对或固定,以及粘性定位)的定位方法的类型. 当设置 position 属性的值为 absolute 时,生成绝对定 ...
- C#获取文件夹/文件的大小以及占用空间 转摘自:http://www.cnblogs.com/chenpeng-dota/articles/2176470.html
C#获取文件夹/文件的大小以及占用空间 今天,头给了个任务:写个方法,我会给你个路径,计算这个路径所占用的磁盘空间 . 然后,找了很多资料.但大部分都是获取文件夹/文件的大小的.对于占用空间的没有成品 ...
- 波兰语 polish
There are several systems for encoding the Polish alphabet for computers. All letters of the Polish ...
- day01 html介绍 文档声明头 head标签 body标签
day01 html 初识html <!--文档的声明--> <!doctype html> <html lang="en"> # ...