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的更多相关文章

  1. JAVA BIO与NIO、AIO的区别

    IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...

  2. java bio 之聊天室

    最近在复习java io相关知识 ,发现很多细节之前没学习到位,原理也没吃透,只能感叹本人愚钝. 复习到bio,顺手写了个简单的聊天室功能,并和大家分享下. 服务端: package io.QQ聊天室 ...

  3. Java BIO及实现

    发现日常学习过的知识不久就会遗忘,在此只是整理并记录一下学习笔记,做个回忆,并方便以后查阅,若有错误,欢迎指正 网络模型:TCP/IP网络模型是从OSI七层模型中演化来的,osi模型分为物理层,数据链 ...

  4. 3. 彤哥说netty系列之Java BIO NIO AIO进化史

    你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...

  5. [转帖]JAVA BIO与NIO、AIO的区别(这个容易理解)

    JAVA BIO与NIO.AIO的区别(这个容易理解) https://blog.csdn.net/ty497122758/article/details/78979302 2018-01-05 11 ...

  6. Java BIO NIO 与 AIO

    回顾 上一章我们介绍了操作系统层面的 IO 模型. 阻塞 IO 模型. 非阻塞 IO 模型. IO 复用模型. 信号驱动 IO 模型(用的不多,知道个概念就行). 异步 IO 模型. 并且介绍了 IO ...

  7. 【转】JAVA BIO与NIO、AIO的区别

    Java中IO的模型分为三种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. BIO[同步阻塞] 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个Ser ...

  8. Java BIO、NIO与AIO的介绍(学习过程)

    Java BIO.NIO与AIO的介绍 因为netty是一个NIO的框架,所以在学习netty的过程中,开始之前.针对于BIO,NIO,AIO进行一个完整的学习. 学习资源分享: Netty学习:ht ...

  9. Netty之JAVA BIO模型

    一.JAVA BIO模型 1.I/O模型 I/O 模型简单的理解:就是用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的性能 Java 共支持 3 种网络编程模型/IO 模式:BIO.NI ...

随机推荐

  1. bug 自定义的json2bean的bug

    bug 在json2bean中如果不进行转换  if(bean instanceof HttpLogin){,将调用的市父类的Json2Meß 此并非最好的解决办法,应该用官方的json.toobje ...

  2. mount -o

    我们的Linux系统在无法启动时候,通常需要进入单用户模式下进行修改一些配置文件,或调整一些参数方可.但是在进入单用户模式后,我们的/文件系统是只读模式,无法进行修改,那么这个时候我们就需要用到一条命 ...

  3. 【SpingBoot】 测试如何使用SpringBoot搭建一个简单后台1

    很久没写博客了,最近接到一个组内的测试开发任务是做一个使用SpringBoot 开发一个后台程序(还未完成),特写感想记录一下 1. 为什么选择SpringBoot ? 首先是目前很多公司的后台还是J ...

  4. centos7下zookeeper安装配置

    1.下载zookeeper文件 cd /opt/ wget http://mirrors.hust.edu.cn/apache/zookeeper/stable/zookeeper-3.4.9.tar ...

  5. Asp.Net Core 第06局:中间件

    总目录 前言 本文介绍Asp.Net Core 中间件. 环境 1.Visual Studio 2017 2.Asp.Net Core 2.2 开局 第一手:中间件概述     1.中间件:添加到应用 ...

  6. 详解linux io flush

    通过本文你会清楚知道 fsync().fdatasync().sync().O_DIRECT.O_SYNC.REQ_PREFLUSH.REQ_FUA的区别和作用. fsync() fdatasync( ...

  7. java的实用类

    1)   Random类 用于生成随机数字,所有生成的数字,都是等概率的. nextInt():生成的值介于int的所有取值范围(-231 ~ 231-1) nextInt(int value):生成 ...

  8. JavaScript学习笔记(基础部分)

    一.JavaScript简介: 概念:JavaScript是一种解释性的.跨平台的.基于对象的脚本语言,一般用于客户端来给HTML页面增加动态的功能. 组成: 1.ECMAScript,描述了该语言的 ...

  9. springcloud费话之Eureka基础

    目录: springcloud费话之Eureka基础 springcloud费话之Eureka集群 springcloud费话之Eureka服务访问(restTemplate) springcloud ...

  10. Struts2后台使用Request和Session方法

    在Struts2后台,如果需要使用Request和Session的话,可以通过下面的方法: 主要是利用了com.opensymphony.xwork2.ActionContext类以及ora.apac ...