3 import java.io.IOException;
4 import java.net.SocketAddress;
5 import java.nio.ByteBuffer;
6 import java.util.concurrent.ConcurrentHashMap;
7 import java.util.concurrent.ConcurrentMap;
8 import java.util.concurrent.atomic.AtomicInteger;
17 private final ConcurrentMap<Short, LspConnection> connectionPool =
new ConcurrentHashMap<>(16);
25 private final ConcurrentMap<Long, LspConnection> connectedSockets =
new ConcurrentHashMap<>(16);
28 private final AtomicInteger idCounter =
new AtomicInteger();
29 private volatile boolean active =
true;
30 private volatile boolean markClosed;
37 private final int port;
40 this.lspSocket =
new LspSocketImpl(port);
41 this.port = this.lspSocket.getPort();
42 this.params = params == null ? LspParams.defaultParams() : params;
57 return lspSocket.receive();
69 final LspConnection conn = connectionPool.get(pack.getConnId());
70 if (conn == null || conn.
isClosed()) {
75 conn.incSendMissing();
100 realCloseConn(connId, conn);
106 Thread.sleep(params.getEpoch());
107 }
catch (InterruptedException e) {
113 private void realCloseConn(
short connId,
final LspConnection conn) {
115 connectionPool.remove(connId);
116 connectedSockets.remove(conn.getSockId());
125 this.markClosed =
true;
137 while (!connectionPool.isEmpty()) {
139 Thread.sleep(params.getEpoch());
140 }
catch (InterruptedException e) {
147 this.lspSocket.close();
150 this.connectionPool.clear();
151 this.connectedSockets.clear();
154 private void checkActive() {
155 if (!active || markClosed)
163 private Short newConnId() {
164 synchronized (idCounter) {
167 if (connectionPool.size() == 65535) {
173 final short id = (short) idCounter.incrementAndGet();
177 if (!connectionPool.containsKey(
id)) {
184 private final class LspSocketImpl
extends LspSocket {
185 LspSocketImpl(
final int port)
throws IOException {
195 void dgramReceiveConnect(
final SocketAddress sockAddr,
final ByteBuffer buf) {
198 if (buf.getInt() == 0) {
199 final long sockId = LspConnection.uniqueSockId(sockAddr);
203 LspConnection conn = connectedSockets.get(sockId);
206 final Short newId = newConnId();
211 ServerTriggers triggers =
new ServerTriggers();
214 conn =
new LspConnection(newId, sockId, sockAddr, params, triggers);
215 connectionPool.put(newId, conn);
216 connectedSockets.put(sockId, conn);
220 triggers.bindedConn = conn;
231 LspConnection usedConnection(
short connId) {
232 return connectionPool.get(connId);
236 private final class ServerTriggers
implements ConnectionTriggers {
237 public LspConnection bindedConn;
240 public void doEpochActions() {
241 Helpers.resendData(lspSocket, bindedConn);
242 Helpers.resendAck(lspSocket, bindedConn);
246 public void doCloseConnection() {
247 realCloseConn(bindedConn.getId(), bindedConn);
Serviço de entrada e saída de pacotes.
Representa uma conexão LSP.
Pack read()
Lê dados da fila de entrada do servidor.
void closeConn(short connId)
Encerra uma conexão com o identificador connId.
LspServer(int port, LspParams params)
final void dgramSendAck(final LspConnection conn, final short seqNum)
void closeAll()
Encerra todas as conexões ativas e a atividade do servidor.
void write(Pack pack)
Envia dados para um determinado cliente.
int getSendMissing()
Número de mensagens na fila, mas faltam enviar.