2014-01-15 4 views
1

지금은 서버 응용 프로그램을 실행하는 raspberry pi가있는 Java 응용 프로그램을 통해 통신하기 위해 Client-Server 응용 프로그램과 함께 약간의 arround를 재생하고 있습니다.Java ServerSocket은 2 개의 연결 만 허용합니다.

글쎄, 문제가 발견되어 가능한 해결책을 찾지 못했습니다. 다음 코드를 사용하면 서버에 두 번 연결할 수 있지만 2를 연결하면 더 이상 연결을 허용하지 않습니다. 예를 들어 처음으로 클라이언트를 시작하면 모든 것이 잘 작동합니다. 그런 다음 클라이언트를 닫고 다시 시작하면 다시 작동합니다. 그러나 내가 그것을 닫고 세 번째로 시작한다면, 그것은 아무 것도하지 않을 것입니다. 서버가 연결을 승인하지 않습니다. 내 사설망에서 다른 PC로 시도했지만 세 번째 연결은 실행되지 않습니다. 여기

내가 서버에서 실행하고있는 코드입니다 :

public class Receiver { 

private final Logger logger = Logger.getLogger(this.getClass().getName()); 

private ServerSocket serverSocket; 
private boolean isRunning; 

public Receiver(int port) { 
    isRunning = true; 
    try { 
     serverSocket = new ServerSocket(port); 
     logger.log(Level.FINER, "start listening at port " + port); 
     logger.log(Level.FINER, "established successful."); 
    } catch (IOException e) { 
     logger.log(Level.SEVERE, "Error while opening socket:\n" + LogUtil.getStackTrace(e)); 
     System.exit(1); 
    } 
} 

/** 
* server starts to listen at the specific port 
*/ 
public void listenServer() { 
    logger.log(Level.FINER, "Server is listening"); 

    while (isRunning) { 
     try { 
      final Socket clientsocket = serverSocket.accept(); 
      logger.log(Level.FINER, "Server accepted Connection from " + clientsocket.getInetAddress()); 
      new Thread(new Runnable() { 

       @Override 
       public void run() { 
        handleConnection(clientsocket); 
       } 
      }).start(); 
     } catch (IOException e) { 
      logger.log(Level.SEVERE, "Connection with Client failed."); 
     } 
    } 
} 

/** 
* handles the given connection 
* 
* @param clientSocket 
*   the given client socket for this connection 
*/ 
private void handleConnection(Socket clientSocket) { 

    ObjectInputStream instream = null; 
    ObjectOutputStream outstream = null; 

    try { 
     outstream = new ObjectOutputStream(clientSocket.getOutputStream()); 
     instream = new ObjectInputStream(clientSocket.getInputStream()); 
     final RequestProcessor processor = new RequestProcessor(); 
     final InetAddress inetAdress = clientSocket.getInetAddress(); 

     logger.log(Level.FINER, "handle connection from " + inetAdress); 

     Object inob; 
     while ((inob = instream.readObject()) != null) { 
      logger.log(Level.FINER, "received Object from " + inetAdress); 
      final ObjectOutputStream finalOutputStream = outstream; 
      final Object finalInob = inob; 

      new Thread() { 
       public void run() { 
        setPriority(MAX_PRIORITY); 
        Object outob; 
        try { 
         outob = processor.processObject(finalInob); 
         logger.log(Level.FINER, "send Respond to: " + inetAdress + " Error: " + (outob instanceof ErrorMessage)); 
         finalOutputStream.writeObject(outob); 
         finalOutputStream.flush(); 
        } catch (IOException e) { 
         logger.log(Level.SEVERE, "Connection closed to " + inetAdress); 
        } 
       } 
      }.start(); 
     } 

     closeConnection(clientSocket, instream, outstream); 
    } catch (IOException e) { 
     logger.log(Level.SEVERE, "Connection closed to " + clientSocket.getInetAddress()); 
    } catch (ClassNotFoundException e) { 
     logger.log(Level.SEVERE, "Connection closed to " + clientSocket.getInetAddress()); 
    } finally { 
     closeConnection(clientSocket, instream, outstream); 
    } 

} 

/** 
* closes InputStream, OutputStream and socket 
* 
* @param socket 
* @param instream 
* @param outstream 
*/ 
private void closeConnection(Socket socket, InputStream instream, OutputStream outstream) { 
    this.isRunning = false; 
    if (instream != null) { 
     try { 
      instream.close(); 
     } catch (IOException e) { 
     } 
    } 
    if (outstream != null) { 
     try { 
      outstream.close(); 
     } catch (IOException e) { 
     } 
    } 
    if (socket != null) { 
     try { 
      socket.close(); 
     } catch (IOException e) { 
     } 
    } 
    logger.log(Level.FINER, "Connection was closed to client " + socket.getInetAddress()); 
} 

/** 
* closes all connections and ends the server 
*/ 
public void endAllConnections() { 
    this.isRunning = false; 

    if (this.serverSocket != null) 
     try { 
      this.serverSocket.close(); 
     } catch (IOException e) { 
      // do nothing 
     } 
     } 
    } 

을 여기에 나는이 서버에 연결하는 데 사용하고있는 클라이언트 코드 :

public class SocketConnector implements IConnector { 

    private final Logger logger = Logger.getLogger(this.getClass().getName()); 

    private Socket s; 
    private ObjectOutputStream oos; 
    private ObjectInputStream ois; 

    /** 
    * creates a new connection 
    * 
    * @param host 
    *   given host 
    * @param port 
    *   given port 
    * 
    * @throws UnknownHostException 
    * @throws IOException 
    */ 
    public SocketConnector(String host, int port) throws UnknownHostException, IOException { 
     logger.log(Level.FINER, "Establish connection to " + host + ":" + port); 
     s = new Socket(host, port); 
     oos = new ObjectOutputStream(s.getOutputStream()); 
     ois = new ObjectInputStream(s.getInputStream()); 
    } 

     // some methos which use oos and ois. 

사람이 아마도 이유를 알고 있나요 2 개의 클라이언트가 연결되고 연결이 끊어지면 서버가 더 이상 연결을 허용하지 않습니까? 나는 많은 수의 arround를 찾았지만 적절한 대답을 찾지 못했습니다./ 서버 로그에 새로운 연결을 받아들이지 않는다고 기록되어 있습니다.

+0

Windows에서 실행 중입니까? TCP/IP 스택 제한은 호스트 당 2 연결로 생각할 수 있습니다. Windows 레지스트리를 사용하거나 IP 주소 및 호스트 이름 같은 대체 호스트 이름을 사용하여 조정할 수 있습니다. –

+0

이 코드에는 다른 문제가 있습니다. 1. 객체 스트림은 생성자가 아닌 run() 메소드에서 만들어야합니다. 그렇지 않으면 accept() 스레드에서 실행되어 잠재적으로이를 차단합니다. 2. ObjectInputStream은 널 (null)을 작성하지 않는 한 널 (null)을 리턴하지 않으므로 널 (null)을 리턴하지 않는 동안 루핑은 의미가 없습니다. 스트림의 끝에서 EOFException을 throw합니다. catch하고 catch하면 깨지게됩니다. @ JasonSperske TCP 백 로그 한도가 있지만 2보다 상당히 높습니다. – EJP

+0

감사합니다. Vutran은 주요한 문제를 해결했습니다. 나는 당신의 충고에 따라 그것을 더 깨끗하게하기 위해 다시 한번 살펴 보겠습니다 EJP :) – chf

답변

2

상황입니다 :) 사전에

감사 :
final Socket clientsocket = serverSocket.accept(); 처음 호출이 첫 번째 클라이언트 기다리고. 첫 번째 클라이언트가 연결되면이 클라이언트를 스레드에 전달한 다음 final Socket clientsocket = serverSocket.accept();을 두 번째로 호출하는 루프를 계속 진행합니다. 스레드를 시작하면 다음 루프로 이동하는 것보다 시간이 더 걸리기 때문에 isRunning은 여전히 ​​true입니다. handleConnection(Socket clientSocket)에서 closeConnection(clientSocket, instream, outstream);으로 전화를 걸어 isRunningfalse으로 설정합니다. 그것이 요점이다. 두 번째 클라이언트가 연결되면이 클라이언트를 다른 스레드로 전달한 다음 isRunningfalse 인 루프를 계속 진행하므로 루프가 종료됩니다. 따라서 세 번째 클라이언트를 얻을 수 없습니다.

+0

고맙습니다 :) 그게 문제였습니다. 부끄러운 나는 그것을 보지 못했다./정말로 내가 거짓으로 설정 한 것을 보지 못했다. ^^ – chf

관련 문제