2013-12-05 1 views
1

Итак, у меня есть следующий код, который ловит новое соединение, а затем передает это соединение своему потоку для обработки клиента.Как бороться с несколькими соединениями с одного и того же IP-адреса?

private void loop(int port) { 
     // Opens a port for connections. 
    ServerSocket serverSocket = null; 
    try { 
     serverSocket = new ServerSocket(port); 
     System.out.println("Server running in port " + port); 
    } catch (IOException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 

     // Listens for a connection 
    while (onlineState == true && serverSocket != null) { 
     Socket clientSocket = new Socket(); 

      try { 

       clientSocket = serverSocket.accept(); 
       System.out.println(clientSocket.getInetAddress() + " has connected to the port " + clientSocket.getPort()); 

       new Thread(new SocketThread(clientSocket)).run(); 

       clientSocket.close(); 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
    } 

Итак, моя проблема в том, что, когда я пытаюсь соединиться с несколькими клиентскими приложениями на сервер, сервер только кажется, или принять одно соединение в любой момент времени. Сам клиент является очень простым приложением основного учебника: он просто повторяет любую строку, которую сервер отправляет ей.

У меня есть два предположения относительно того, почему это происходит: а) с моим кодом обработки что-то не так, b) это потому, что оба соединения связаны с одним и тем же IP-адресом.

Однако ни один случай не является хорошим. Любые идеи, что я делаю неправильно? (Кроме всего)

+1

Различные соединения с одного и того же IP-адреса будут иметь другой порт источника. – Raedwald

+1

Вы хотите закрыть clientSocket сразу после запуска потока? Возможно, у него есть только один за раз, потому что предыдущее соединение закрывается перед началом нового подключения. – DoubleDouble

+0

Вам не нужно создавать новый Socket, вам просто нужно вызвать accept(). В общем случае плохой практикой является инициализация переменных, которые назначаются на самой следующей строке. В этом случае это не просто плохая практика, это утечка FD. И вы, конечно, должны * не закрывать его в цикле принятия. Поток должен закрывать его, когда он получает конец потока. – EJP

ответ

2

Две вещи:

  1. Вы хотите позвонить start(), не run() на вашем Thread объекта. Разница в том, что start() на самом деле идет и делает резьбовые вещи, как работает в фоновом режиме. Вызов run(), откуда вы его называете, будет обрабатывать все клиентские сообщения прямо там, inline. Вот почему вы только принимаете одно соединение - вы больше не будете принимать, пока не будете обслуживать этого клиента.

  2. Вы не хотите называть clientSocket.close() в своей основной теме. В вашей реализации SocketThread вызовите clientSocket.close() в конце вашего метода run(), возможно, внутри блока finally.

Кроме того, не SocketThread продлить Thread? Если да, то вам не нужно new Thread(), просто сделать

new SocketThread(clientSocket).start(); 

Если он не распространяется Thread, почему бы не назвать его SocketRunnable или ClientRunnable или что-то подобное.

+0

Я на самом деле назвал это так, потому что я хочу знать из названия, что я хочу, чтобы класс делал. Но, похоже, эта «некорректность» фактически привела к тому, что я получил новые полезные знания по этой теме. – Rogem

Смежные вопросы