Add javadocs in the oio package and also fix some intellij warnings
This commit is contained in:
parent
6d93c3fb25
commit
8d89e48177
@ -23,10 +23,16 @@ import io.netty.channel.ChannelPipeline;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for OIO which reads and writes bytes from/to a Socket
|
||||||
|
*/
|
||||||
abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
||||||
|
|
||||||
private volatile boolean inputShutdown;
|
private volatile boolean inputShutdown;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AbstractOioByteChannel#AbstractOioByteChannel(Channel, Integer)
|
||||||
|
*/
|
||||||
protected AbstractOioByteChannel(Channel parent, Integer id) {
|
protected AbstractOioByteChannel(Channel parent, Integer id) {
|
||||||
super(parent, id);
|
super(parent, id);
|
||||||
}
|
}
|
||||||
@ -36,7 +42,7 @@ abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected OioByteUnsafe newUnsafe() {
|
protected AbstractOioUnsafe newUnsafe() {
|
||||||
return new OioByteUnsafe();
|
return new OioByteUnsafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +138,26 @@ abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
|||||||
buf.clear();
|
buf.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of bytes ready to read from the underlying Socket.
|
||||||
|
*/
|
||||||
protected abstract int available();
|
protected abstract int available();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read bytes from the underlying Socket.
|
||||||
|
*
|
||||||
|
* @param buf the {@link ByteBuf} into which the read bytes will be written
|
||||||
|
* @return amount the number of bytes read. This may return a negative amount if the underlying
|
||||||
|
* Socket was closed
|
||||||
|
* @throws Exception is thrown if an error accoured
|
||||||
|
*/
|
||||||
protected abstract int doReadBytes(ByteBuf buf) throws Exception;
|
protected abstract int doReadBytes(ByteBuf buf) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the data which is hold by the {@link ByteBuf} to the underlying Socket.
|
||||||
|
*
|
||||||
|
* @param buf the {@link ByteBuf} which holds the data to transfer
|
||||||
|
* @throws Exception is thrown if an error accoured
|
||||||
|
*/
|
||||||
protected abstract void doWriteBytes(ByteBuf buf) throws Exception;
|
protected abstract void doWriteBytes(ByteBuf buf) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,18 @@ import io.netty.channel.EventLoop;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for {@link Channel} implementations that use Old-Blocking-IO
|
||||||
|
*/
|
||||||
abstract class AbstractOioChannel extends AbstractChannel {
|
abstract class AbstractOioChannel extends AbstractChannel {
|
||||||
|
|
||||||
static final int SO_TIMEOUT = 1000;
|
static final int SO_TIMEOUT = 1000;
|
||||||
|
|
||||||
protected volatile boolean readSuspended;
|
protected volatile boolean readSuspended;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AbstractChannel#AbstractChannel(io.netty.channel.Channel, Integer)
|
||||||
|
*/
|
||||||
protected AbstractOioChannel(Channel parent, Integer id) {
|
protected AbstractOioChannel(Channel parent, Integer id) {
|
||||||
super(parent, id);
|
super(parent, id);
|
||||||
}
|
}
|
||||||
@ -115,6 +121,9 @@ abstract class AbstractOioChannel extends AbstractChannel {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the remote peer using the given localAddress if one is specified or null otherwise.
|
||||||
|
*/
|
||||||
protected abstract void doConnect(
|
protected abstract void doConnect(
|
||||||
SocketAddress remoteAddress, SocketAddress localAddress) throws Exception;
|
SocketAddress remoteAddress, SocketAddress localAddress) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,20 @@ import io.netty.channel.ChannelPipeline;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for OIO which reads and writes objects from/to a Socket
|
||||||
|
*/
|
||||||
abstract class AbstractOioMessageChannel extends AbstractOioChannel {
|
abstract class AbstractOioMessageChannel extends AbstractOioChannel {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AbstractOioChannel#AbstractOioChannel(Channel, Integer)
|
||||||
|
*/
|
||||||
protected AbstractOioMessageChannel(Channel parent, Integer id) {
|
protected AbstractOioMessageChannel(Channel parent, Integer id) {
|
||||||
super(parent, id);
|
super(parent, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected OioMessageUnsafe newUnsafe() {
|
protected AbstractOioUnsafe newUnsafe() {
|
||||||
return new OioMessageUnsafe();
|
return new OioMessageUnsafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +81,21 @@ abstract class AbstractOioMessageChannel extends AbstractOioChannel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read Objects from the underlying Socket.
|
||||||
|
*
|
||||||
|
* @param buf the {@link MessageBuf} into which the read objects will be written
|
||||||
|
* @return amount the number of objects read. This may return a negative amount if the underlying
|
||||||
|
* Socket was closed
|
||||||
|
* @throws Exception is thrown if an error accoured
|
||||||
|
*/
|
||||||
protected abstract int doReadMessages(MessageBuf<Object> buf) throws Exception;
|
protected abstract int doReadMessages(MessageBuf<Object> buf) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the Objects which is hold by the {@link MessageBuf} to the underlying Socket.
|
||||||
|
*
|
||||||
|
* @param buf the {@link MessageBuf} which holds the data to transfer
|
||||||
|
* @throws Exception is thrown if an error accoured
|
||||||
|
*/
|
||||||
protected abstract void doWriteMessages(MessageBuf<Object> buf) throws Exception;
|
protected abstract void doWriteMessages(MessageBuf<Object> buf) throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,10 @@ import java.net.SocketException;
|
|||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link DatagramChannel} implementation which use Old-Blocking-IO. It can be used to read and write
|
||||||
|
* {@link DatagramPacket}s via UDP.
|
||||||
|
*/
|
||||||
public class OioDatagramChannel extends AbstractOioMessageChannel
|
public class OioDatagramChannel extends AbstractOioMessageChannel
|
||||||
implements DatagramChannel {
|
implements DatagramChannel {
|
||||||
|
|
||||||
@ -60,14 +64,28 @@ public class OioDatagramChannel extends AbstractOioMessageChannel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance with an new {@link MulticastSocket}.
|
||||||
|
*/
|
||||||
public OioDatagramChannel() {
|
public OioDatagramChannel() {
|
||||||
this(newSocket());
|
this(newSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link MulticastSocket}.
|
||||||
|
*
|
||||||
|
* @param socket the {@link MulticastSocket} which is used by this instance
|
||||||
|
*/
|
||||||
public OioDatagramChannel(MulticastSocket socket) {
|
public OioDatagramChannel(MulticastSocket socket) {
|
||||||
this(null, socket);
|
this(null, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link MulticastSocket}.
|
||||||
|
*
|
||||||
|
* @param id the id which should be used for this instance or {@code null} if a new one should be generated
|
||||||
|
* @param socket the {@link MulticastSocket} which is used by this instance
|
||||||
|
*/
|
||||||
public OioDatagramChannel(Integer id, MulticastSocket socket) {
|
public OioDatagramChannel(Integer id, MulticastSocket socket) {
|
||||||
super(null, id);
|
super(null, id);
|
||||||
|
|
||||||
|
@ -32,8 +32,13 @@ import java.util.concurrent.Executors;
|
|||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link EventLoopGroup} which is used to handle OIO {@link Channel}'s. Each {@link Channel} will be handled by its
|
||||||
|
* own {@link EventLoop} to not block others.
|
||||||
|
*/
|
||||||
public class OioEventLoopGroup implements EventLoopGroup {
|
public class OioEventLoopGroup implements EventLoopGroup {
|
||||||
|
|
||||||
|
private static final StackTraceElement[] STACK_ELEMENTS = new StackTraceElement[0];
|
||||||
private final int maxChannels;
|
private final int maxChannels;
|
||||||
final ChannelTaskScheduler scheduler;
|
final ChannelTaskScheduler scheduler;
|
||||||
final ThreadFactory threadFactory;
|
final ThreadFactory threadFactory;
|
||||||
@ -42,14 +47,37 @@ public class OioEventLoopGroup implements EventLoopGroup {
|
|||||||
final Queue<OioEventLoop> idleChildren = new ConcurrentLinkedQueue<OioEventLoop>();
|
final Queue<OioEventLoop> idleChildren = new ConcurrentLinkedQueue<OioEventLoop>();
|
||||||
private final ChannelException tooManyChannels;
|
private final ChannelException tooManyChannels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link OioEventLoopGroup} with no limit in place.
|
||||||
|
*/
|
||||||
public OioEventLoopGroup() {
|
public OioEventLoopGroup() {
|
||||||
this(0);
|
this(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link OioEventLoopGroup}.
|
||||||
|
*
|
||||||
|
* @param maxChannels the maximum number of channels to handle with this instance. Once you try to register
|
||||||
|
* a new {@link Channel} and the maximum is exceed it will throw an
|
||||||
|
* {@link ChannelException} on the {@link #register(Channel)} and
|
||||||
|
* {@link #register(Channel, ChannelFuture)} method.
|
||||||
|
* Use {@code 0} to use no limit
|
||||||
|
*/
|
||||||
public OioEventLoopGroup(int maxChannels) {
|
public OioEventLoopGroup(int maxChannels) {
|
||||||
this(maxChannels, Executors.defaultThreadFactory());
|
this(maxChannels, Executors.defaultThreadFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@link OioEventLoopGroup}.
|
||||||
|
*
|
||||||
|
* @param maxChannels the maximum number of channels to handle with this instance. Once you try to register
|
||||||
|
* a new {@link Channel} and the maximum is exceed it will throw an
|
||||||
|
* {@link ChannelException} on the {@link #register(Channel)} and
|
||||||
|
* {@link #register(Channel, ChannelFuture)} method.
|
||||||
|
* Use {@code 0} to use no limit
|
||||||
|
* @param threadFactory the {@link ThreadFactory} used to create new {@link Thread} instances that handle the
|
||||||
|
* registered {@link Channel}s
|
||||||
|
*/
|
||||||
public OioEventLoopGroup(int maxChannels, ThreadFactory threadFactory) {
|
public OioEventLoopGroup(int maxChannels, ThreadFactory threadFactory) {
|
||||||
if (maxChannels < 0) {
|
if (maxChannels < 0) {
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(String.format(
|
||||||
@ -65,7 +93,7 @@ public class OioEventLoopGroup implements EventLoopGroup {
|
|||||||
scheduler = new ChannelTaskScheduler(threadFactory);
|
scheduler = new ChannelTaskScheduler(threadFactory);
|
||||||
|
|
||||||
tooManyChannels = new ChannelException("too many channels (max: " + maxChannels + ')');
|
tooManyChannels = new ChannelException("too many channels (max: " + maxChannels + ')');
|
||||||
tooManyChannels.setStackTrace(new StackTraceElement[0]);
|
tooManyChannels.setStackTrace(STACK_ELEMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,6 +43,13 @@ import java.util.HashSet;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link io.netty.channel.socket.SctpChannel} implementation which use blocking mode and allows to read / write
|
||||||
|
* {@link SctpMessage}s to the underlying {@link SctpChannel}.
|
||||||
|
*
|
||||||
|
* Be aware that not all operations systems support SCTP. Please refer to the documentation of your operation system,
|
||||||
|
* to understand what you need to do to use it. Also this feature is only supported on Java 7+.
|
||||||
|
*/
|
||||||
public class OioSctpChannel extends AbstractOioMessageChannel
|
public class OioSctpChannel extends AbstractOioMessageChannel
|
||||||
implements io.netty.channel.socket.SctpChannel {
|
implements io.netty.channel.socket.SctpChannel {
|
||||||
|
|
||||||
@ -63,14 +70,30 @@ public class OioSctpChannel extends AbstractOioMessageChannel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance with an new {@link SctpChannel}.
|
||||||
|
*/
|
||||||
public OioSctpChannel() {
|
public OioSctpChannel() {
|
||||||
this(openChannel());
|
this(openChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link SctpChannel}.
|
||||||
|
*
|
||||||
|
* @param ch the {@link SctpChannel} which is used by this instance
|
||||||
|
*/
|
||||||
public OioSctpChannel(SctpChannel ch) {
|
public OioSctpChannel(SctpChannel ch) {
|
||||||
this(null, null, ch);
|
this(null, null, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link SctpChannel}.
|
||||||
|
*
|
||||||
|
* @param parent the parent {@link Channel} which was used to create this instance. This can be null if the
|
||||||
|
* {@link} has no parent as it was created by your self.
|
||||||
|
* @param id the id which should be used for this instance or {@code null} if a new one should be generated
|
||||||
|
* @param ch the {@link SctpChannel} which is used by this instance
|
||||||
|
*/
|
||||||
public OioSctpChannel(Channel parent, Integer id, SctpChannel ch) {
|
public OioSctpChannel(Channel parent, Integer id, SctpChannel ch) {
|
||||||
super(parent, id);
|
super(parent, id);
|
||||||
this.ch = ch;
|
this.ch = ch;
|
||||||
|
@ -34,6 +34,13 @@ import java.util.HashSet;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link io.netty.channel.socket.SctpServerChannel} implementation which use blocking mode to accept new connections
|
||||||
|
* and create the {@link OioSctpChannel} for them.
|
||||||
|
*
|
||||||
|
* Be aware that not all operations systems support SCTP. Please refer to the documentation of your operation system,
|
||||||
|
* to understand what you need to do to use it. Also this feature is only supported on Java 7+.
|
||||||
|
*/
|
||||||
public class OioSctpServerChannel extends AbstractOioMessageChannel
|
public class OioSctpServerChannel extends AbstractOioMessageChannel
|
||||||
implements io.netty.channel.socket.SctpServerChannel {
|
implements io.netty.channel.socket.SctpServerChannel {
|
||||||
|
|
||||||
@ -53,14 +60,28 @@ public class OioSctpServerChannel extends AbstractOioMessageChannel
|
|||||||
final SctpServerChannel sch;
|
final SctpServerChannel sch;
|
||||||
private final SctpServerChannelConfig config;
|
private final SctpServerChannelConfig config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance with an new {@link SctpServerChannel}
|
||||||
|
*/
|
||||||
public OioSctpServerChannel() {
|
public OioSctpServerChannel() {
|
||||||
this(newServerSocket());
|
this(newServerSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link SctpServerChannel}
|
||||||
|
*
|
||||||
|
* @param sch the {@link SctpServerChannel} which is used by this instance
|
||||||
|
*/
|
||||||
public OioSctpServerChannel(SctpServerChannel sch) {
|
public OioSctpServerChannel(SctpServerChannel sch) {
|
||||||
this(null, sch);
|
this(null, sch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link SctpServerChannel}
|
||||||
|
*
|
||||||
|
* @param id the id which should be used for this instance or {@code null} if a new one should be generated
|
||||||
|
* @param sch the {@link SctpServerChannel} which is used by this instance
|
||||||
|
*/
|
||||||
public OioSctpServerChannel(Integer id, SctpServerChannel sch) {
|
public OioSctpServerChannel(Integer id, SctpServerChannel sch) {
|
||||||
super(null, id);
|
super(null, id);
|
||||||
if (sch == null) {
|
if (sch == null) {
|
||||||
|
@ -34,6 +34,11 @@ import java.net.SocketTimeoutException;
|
|||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ServerSocketChannel} which accepts new connections and create the {@link OioSocketChannel}'s for them.
|
||||||
|
*
|
||||||
|
* This implementation use Old-Blocking-IO.
|
||||||
|
*/
|
||||||
public class OioServerSocketChannel extends AbstractOioMessageChannel
|
public class OioServerSocketChannel extends AbstractOioMessageChannel
|
||||||
implements ServerSocketChannel {
|
implements ServerSocketChannel {
|
||||||
|
|
||||||
@ -54,14 +59,28 @@ public class OioServerSocketChannel extends AbstractOioMessageChannel
|
|||||||
final Lock shutdownLock = new ReentrantLock();
|
final Lock shutdownLock = new ReentrantLock();
|
||||||
private final ServerSocketChannelConfig config;
|
private final ServerSocketChannelConfig config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance with an new {@link Socket}
|
||||||
|
*/
|
||||||
public OioServerSocketChannel() {
|
public OioServerSocketChannel() {
|
||||||
this(newServerSocket());
|
this(newServerSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link ServerSocket}
|
||||||
|
*
|
||||||
|
* @param socket the {@link ServerSocket} which is used by this instance
|
||||||
|
*/
|
||||||
public OioServerSocketChannel(ServerSocket socket) {
|
public OioServerSocketChannel(ServerSocket socket) {
|
||||||
this(null, socket);
|
this(null, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link ServerSocket}
|
||||||
|
*
|
||||||
|
* @param id the id which should be used for this instance or {@code null} if a new one should be generated
|
||||||
|
* @param socket the {@link ServerSocket} which is used by this instance
|
||||||
|
*/
|
||||||
public OioServerSocketChannel(Integer id, ServerSocket socket) {
|
public OioServerSocketChannel(Integer id, ServerSocket socket) {
|
||||||
super(null, id);
|
super(null, id);
|
||||||
if (socket == null) {
|
if (socket == null) {
|
||||||
|
@ -39,6 +39,9 @@ import java.nio.channels.Channels;
|
|||||||
import java.nio.channels.NotYetConnectedException;
|
import java.nio.channels.NotYetConnectedException;
|
||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link SocketChannel} which is using Old-Blocking-IO
|
||||||
|
*/
|
||||||
public class OioSocketChannel extends AbstractOioByteChannel
|
public class OioSocketChannel extends AbstractOioByteChannel
|
||||||
implements SocketChannel {
|
implements SocketChannel {
|
||||||
|
|
||||||
@ -53,14 +56,30 @@ public class OioSocketChannel extends AbstractOioByteChannel
|
|||||||
private OutputStream os;
|
private OutputStream os;
|
||||||
private WritableByteChannel outChannel;
|
private WritableByteChannel outChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance with an new {@link Socket}
|
||||||
|
*/
|
||||||
public OioSocketChannel() {
|
public OioSocketChannel() {
|
||||||
this(new Socket());
|
this(new Socket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link Socket}
|
||||||
|
*
|
||||||
|
* @param socket the {@link Socket} which is used by this instance
|
||||||
|
*/
|
||||||
public OioSocketChannel(Socket socket) {
|
public OioSocketChannel(Socket socket) {
|
||||||
this(null, null, socket);
|
this(null, null, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance from the given {@link Socket}
|
||||||
|
*
|
||||||
|
* @param parent the parent {@link Channel} which was used to create this instance. This can be null if the
|
||||||
|
* {@link} has no parent as it was created by your self.
|
||||||
|
* @param id the id which should be used for this instance or {@code null} if a new one should be generated
|
||||||
|
* @param socket the {@link Socket} which is used by this instance
|
||||||
|
*/
|
||||||
public OioSocketChannel(Channel parent, Integer id, Socket socket) {
|
public OioSocketChannel(Channel parent, Integer id, Socket socket) {
|
||||||
super(parent, id);
|
super(parent, id);
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
|
Loading…
Reference in New Issue
Block a user