2017-01-09 3 views
0

Ich habe einen Java-Server (Java 1.6, falls es hilft), die Socket-Verbindungen akzeptiert und dann startet Threads, um sie zu lösen, wie alle regulären Multithreading-Server. Aber ich kann keine gleichzeitige Verbindung herstellen. Ich verbinde einen Client, der ständig eine Nachricht sendet und empfängt, und versuche, eine zweite zu verbinden, aber die zweite gibt immer eine BindException zurück und sagt mir, dass die Adresse bereits verwendet wird. Bekomme ich die ganze Multithreading-Sache falsch, sei es konzeptionell oder in meinem Code?Kann keine gleichzeitige Verbindungen zu einem Server

My Server:

ServerSocket serverSocketUPMS1 = null; 
    try { 
     serverSocketUPMS1 = new ServerSocket(Integer.parseInt(cfg.getProperty("UPMSServerPort"))); 
     serverSocketUPMS1.setSoTimeout(0); 
     log.info("Starting the USSDInterface server at port "+serverSocketUPMS1.getLocalPort()); 
    } catch (IOException e) { 
     log.error("The TCP server couldn't be started",e); 
     finish = true; 
    } 

    while (!finish) { 
      try { 
       log.info("Waiting for a socket to connect..."); 
       Socket subscriberSocket = serverSocketUPMS1.accept(); 
       //Timeout de sesion ussd para poder crear una TimeoutException 
       int timeOutSocket = Integer.parseInt(cfg.getProperty("USSDSocketTimeout")); 
       log.info("New client arrived from " + subscriberSocket.getRemoteSocketAddress()); 

       upms = new USSDSocket2(subscriberSocket,timeOutSocket); 
       Thread t1 = new Thread(upms); 
       t1.setName(Integer.toString(subscriberSocket.getLocalPort()) +","+ subscriberSocket.getRemoteSocketAddress() +", upms"); 
       t1.start(); 
       UPMSSimUtils.createAvailableInstance(upms); 
       log.trace("USSD Socket created and initiated"); 
      } 
      catch (Exception e) { 
       log.warn("There's been an error while working with the server socket"+e.getMessage(), e); 
       try { 
        Thread.sleep(100); 
       } catch (InterruptedException e1) { 
        log.warn("There's been an error while waiting to resume the socket listenting"+e1.getMessage(), e1); 
       } 
      } 
     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
      log.warn("There's been an error while waiting in the server"+e.getMessage(), e); 
     } 
    } 

    try { 
     serverSocketUPMS1.close(); 
     log.info("TCP Server is now DOWN"); 
    } catch (IOException e) { 
     log.error("There was an error while closing the server socket. TCP Server is now DOWN",e); 
    } 
    upms.stop(); 

Der Verarbeitungsthread:

public void run() { 
    new Thread(new Sender()).start(); 
    while (!finish) { 
     byte buffer[] = new byte[10000]; 
     byte size[] = new byte[4]; 
     try { 
      this.socket.getInputStream().read(size, 0, 4); 
      Integer largo = calcularTamanio(size); 
      log.debug("Size in bytes: "+size); 
      log.debug("Length of the incoming string: " + largo); 
      this.socket.getInputStream().read(buffer, 0, largo); 
      log.debug("Buffer of the incoming string: " + tostr2(buffer)); 
      decodeMessage(parseXML(toStr(buffer)), toStr(buffer)); 

     } catch (SocketException e) { 
      log.error("Socket exception: " + e.getMessage(), e); 
      this.finish = true; 
     } catch (IOException e) { 
      log.error("IO exception: " + e.getMessage(), e); 
      this.finish = true; 
     } catch (JDOMException e) { 
      log.error("JDOM exception: " + e.getMessage(), e); 
     } catch (Exception e) { 
      log.error("Unknown exception: " + e.getMessage(), e); 
      this.finish = true; 
     } 
     // try { 
     // Thread.sleep(1); 
     // } catch (InterruptedException e) { 
     // log.error(e.getMessage(), e); 
     // } 
    } 
    try { 
     this.socket.close(); 
     this.socketUDP.close(); 
    } catch (IOException e) { 
     log.error("Error closing the sockets at the USSDSocket", e); 
    } 
} 

Die Schaffung der Client-Socket:

try{ 
       socketsCreated++; 
       log.info("Attempting to create a socket"); 
       Properties properties=Config.getInstance().getCfg(); 

       ussdIface = new USSDInterfaceServerClass(properties); 

       int port=Integer.parseInt(properties.getProperty("TestClientSocketTargetPort")); 

       log.info("Client will connect to "+properties.getProperty("TestClientSocketTargetAddress")+":"+port); 

       clientSocket = new Socket(properties.getProperty("TestClientSocketTargetAddress"),port); 
       log.info("Socket connected"); 
       log.info("Client socket targeting "+properties.getProperty("TestClientSocketTargetAddress")+":"+port+" created"); 

       USSDSocket2 ussdSocket=new USSDSocket2(clientSocket,Integer.parseInt(properties.getProperty("USSDSocketTimeout"))); 
       UPMSSimUtils.createAvailableInstance(ussdSocket); 

       upms = UPMSSimUtils.getAvailable(properties); 

       Thread t1 = new Thread(ussdSocket); 
       t1.setName("ussdsocket client test"); 
       t1.start(); 

       log.info("USSDSocket setted on the UPMSSimUtils"); 

       USSDSocketClientThread socketClientThread=instance.new USSDSocketClientThread(upms, "ClientSocketThread-"+socketsCreated); 
       openSockets.add(socketClientThread); 
       new Thread(socketClientThread).start(); 

       Thread.sleep(waitTimeBetweenConnections); 
      }catch(Throwable throwable){ 
       log.warn("Error with a new connection",throwable); 
       socketsCreated--; 
      } 

die einzige Funktion, die Daten über den Socket sendet:

public void send(String message) throws IOException { 
    log.info("Trying to send message "+message); 
    if (message != null && !"".equals(message)) { 
     int largo = message.length(); 
     // largo = 800; 
     byte largobytes[] = new byte[4]; 
     largobytes[0] = (byte) (largo % 256); 
     largobytes[1] = (byte) (largo/256); 
     largobytes[2] = (byte) (largo & 0x00FF0000); 
     largobytes[3] = 0; 
     this.socket.getOutputStream().write(largobytes); 
     log.trace("Byte length sent: "+largobytes); 
     this.socket.getOutputStream().write(message.getBytes()); 
     log.info("Message sent successfully"); 
    } 
} 

Der Verarbeitungs-Thread ist dafür zuständig, alles zu lesen, was durch den Socket kommt. Anschließend erstellt decodeMessage eine Antwort, die nach der Verarbeitung über denselben Socket gesendet wird. Eine andere Utilitarklasse ermöglicht es mir, Nachrichten über den Socket zu senden, indem ich darauf Verweise anlege und auf ihre Antworten warte.

Ich weiß nicht, ob es die Art und Weise ist, die ich aus den Input/Output Streams lese oder was (verwendet die einfachen Streams bindet oder blockiert die Steckdose?), Aber es ist wirklich ärgerlich, wie jedes Beispiel mir das zu sagen scheint Was ich mache, ist in Ordnung, wenn es mir solche Fehler gibt.

+0

Ist "upms" eine globale Variable? Es scheint so, und wenn ja, überschreibt die zweite Verbindung die "upms" und beide Client-Threads arbeiten mit dem gleichen Socket. –

+0

'upms' ist keine globale Variable, ist ein Parameter der Thread-Klasse, die gesetzt wird, bevor der Thread gestartet wird. Tut mir leid, ich hätte das klären sollen. Ich werde es jetzt korrigieren. – KatVolkov

+0

Das Abrufen einer BindException ist während einer Clientverbindung ungewöhnlich, da der Quellport flüchtig ist und daher nicht gebunden sein sollte. Rufen Sie beim Verbinden explizit bind() auf dem Socket auf? Können Sie Ihren Kundencode posten? Wir müssen sehen, was es macht, wenn es eine Ausnahme auslöst. –

Antwort

0

Vergiss alles. Der Fehler war, dass der ursprüngliche Hersteller des Codes einen hardcoded Socket verließ, der auf einem hardcoded Port einleitete. Da der Socket nicht benutzt wurde, habe ich nie bemerkt, dass er existiert (ich nahm fälschlicherweise an, dass die Stack-Spur des Fehlers zum eigentlichen Arbeitsanschluss führte, aber das war nicht so)

Verwandte Themen