/** 把当前客户端信息 推送到其他客户端 */
  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);
    }
  }
Exemple #3
0
  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());
    }
  }