/** 把当前客户端信息 推送到其他客户端 */ private void dispatch(SocketChannel client, String info) throws IOException { Socket s = client.socket(); String name = "[" + s.getInetAddress().toString().substring(1) + ":" + Integer.toHexString(client.hashCode()) + "]"; if (!clientsMap.isEmpty()) { for (Map.Entry<String, SocketChannel> entry : clientsMap.entrySet()) { SocketChannel temp = entry.getValue(); if (!client.equals(temp)) { sendBuffer.clear(); sendBuffer.put((name + ":" + info).getBytes()); sendBuffer.flip(); // 输出到通道 temp.write(sendBuffer); } } } clientsMap.put(name, client); }
public void run() { Selector selector = null; try { curSocketChannel = SocketChannel.open(); InetSocketAddress isa = new InetSocketAddress(curHost, curPort); curSocketChannel.connect(isa); curSocketChannel.configureBlocking(false); selector = Selector.open(); curSocketChannel.register(selector, SelectionKey.OP_READ); servers.put(curHost, curSocketChannel); send(curSocketChannel, MessageUtils.hello(clientName)); } catch (Exception ex) { System.err.println("Error in getting connection: " + ex.getMessage()); System.exit(1); } try { while (true) { int num = selector.select(); if (num == 0) { continue; } Set keys = selector.selectedKeys(); Iterator it = keys.iterator(); while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { SocketChannel sc = null; try { sc = (SocketChannel) key.channel(); if (sc.equals(curSocketChannel)) { boolean ok = processInput(sc); if (!ok) { key.cancel(); Socket s = null; try { s = sc.socket(); s.close(); } catch (IOException ie) { System.err.println("Error closing socket " + s + ": " + ie); System.exit(1); } } } } catch (IOException ie) { key.cancel(); String serverToQuitFrom = getKey(sc); if (serverToQuitFrom != null) { IOUtils.closeFile(serverToQuitFrom, sc); servers.remove(serverToQuitFrom); System.out.println(serverToQuitFrom + " was closed."); } } } } keys.clear(); } } catch (Exception ex) { System.err.println(ex.getMessage()); System.exit(1); } }
public static void checkClients(List<SocketChannel> anonymousClients) { try { if (selector.selectNow() == 0) { return; } Set<SelectionKey> keys = selector.selectedKeys(); for (SelectionKey key : keys) { if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { SocketChannel clientSocket = serverSocket.accept(); if (clientSocket == null) { System.err.println("Error: can not accept"); continue; } anonymousClients.add(clientSocket); clientSocket.configureBlocking(false); clientSocket.register(selector, SelectionKey.OP_READ); } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { SocketChannel clientSocket = (SocketChannel) key.channel(); ByteBuffer bytes = ByteBuffer.allocate(4096); if (clientSocket.read(bytes) != -1) { byte[] message = bytes.array(); switch (message[0]) { case 1: { String nick = MessageUtils.parseMessage(message).first; if (!checkMessage(nick, "", clientSocket)) { continue; } if (clients.containsKey(nick) || nick.length() > 32) { if (nick.length() > 32) { sendMessage( clientSocket, MessageUtils.error("<server>: your nick is too long")); } else { sendMessage( clientSocket, MessageUtils.error("<server>: another user is using this nick")); } sendMessage(clientSocket, MessageUtils.bye()); anonymousClients.remove(clientSocket); Utils.tryClose(clientSocket); } else { System.out.println(nick + " enter this chatroom"); notifyAllClients(nick + " enter this chatroom"); sendMessage( clientSocket, MessageUtils.message("<server>", "Wellcome, your nick is " + nick)); anonymousClients.remove(clientSocket); clients.put(nick, clientSocket); } break; } case 2: { String nick = getNickFromSocket(clientSocket); if (nick == null) { Utils.printErrorAndExit("Error: it could not happen"); } Utils.Pair<String, String> pair = MessageUtils.parseMessage(message); if (!checkMessage(pair.first, pair.second, clientSocket)) { continue; } if (!pair.first.equals(nick)) { System.out.println("Cheater: " + nick); sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat")); } for (Entry<String, SocketChannel> client : clients.entrySet()) { if (!clientSocket.equals(client.getValue())) { sendMessage(client.getValue(), MessageUtils.message(nick, pair.second)); } } break; } case 3: disconnectClient(clientSocket); break; case 127: { String nick = getNickFromSocket(clientSocket); Utils.Pair<String, String> pair = MessageUtils.parseMessage(message); if (!checkMessage(pair.first, pair.second, clientSocket)) { continue; } if (!pair.first.equals(nick)) { System.out.println("Cheater: " + nick); sendMessage(clientSocket, MessageUtils.message("<server>", "do not cheat")); } System.out.println(nick + ": " + pair.second); break; } default: System.out.println("Bad message from " + getNickFromSocket(clientSocket)); sendMessage(clientSocket, MessageUtils.message("<server>", "bad message")); break; } } else { disconnectClient(clientSocket); } } } keys.clear(); } catch (Exception expt) { expt.printStackTrace(); Utils.printErrorAndExit(expt.getMessage()); } }