2017-02-01 6 views
0

Ich habe folgende Server geschrieben, die an einen Client verbindet:Empfangen von Nachrichten von Client-

ServerSocket server = null; 

try 
{ 
    server = new ServerSocket(4040); 

    while (isServerListening) 
    { 
     Socket clientSocket = server.accept(); 

     // Send bytes to the Client 
     ServerOutputStream = clientSocket.getOutputStream(); 

     byte[] bytes = "I am a Server".getBytes(); 
     ServerOutputStream.write(bytes); 
    } 
} 
catch (IOException e) 
{ 
    e.printStackTrace(); 
} 
finally 
{ 
    // close socket here 
} 

Dieser Server hält an Linie server.accept() und wartet auf nächsten Kunden zu verbinden. Gleichzeitig möchte ich die vom Client empfangenen Nachrichten lesen.

Ich habe diese Socket-Programmierung über Event-Handler vor einigen Jahren in verschiedenen Sprachen gemacht, aber hier scheint es, dass ich einen anderen Ansatz brauche.

Meine Frage ist: Würde ich einen anderen Thread für diese Aufgabe benötigen? Gibt es eine Alternative, z.B. nicht blockierender Modus?

+0

Bräuchte Sie einen anderen Thread? Natürlich ja. Und nein, es gibt keine andere Alternative. –

+0

@HovercraftFullOfEels: Wirklich nicht so etwas wie nicht blockierende Steckdose mit gleichem Gewinde? – user963241

+0

Verwenden Sie einfach Threading; Genau dafür ist es da. –

Antwort

1

finden einreichen Meine Frage ist: Brauche ich einen anderen Thread für diese Aufgabe?

Eine Möglichkeit besteht darin, für jede Clientverbindung einen Thread zu verwenden. Die Anwendungsmethode führt den Server in einer Endlosschleife aus, die den Port überwacht. Wenn eine Verbindung angefordert wird, erzeugt sie einen neuen Thread für die Wartung und kehrt sofort zum Abhören zurück.

ServerSocket listener = new ServerSocket(9898); 
try { 
    while (true) { 
     new Handler(listener.accept(), clientNumber++).start(); 
    } 
} finally { 
    listener.close(); 
} 

Ein Thread, um Anfragen auf einem bestimmten Socket zu behandeln.

private static class Handler extends Thread { 
    private Socket socket; 
    private int clientNumber; 

    public Handler(Socket socket, int clientNumber) { 
     this.socket = socket; 
     this.clientNumber = clientNumber; 
    } 

    public void run() { 
     try { 
      BufferedReader in = new BufferedReader(
        new InputStreamReader(socket.getInputStream())); 
      PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 

      while (true) { 
       String input = in.readLine(); 
       ... 
      } 
     } catch (IOException e) { 
     } finally { 
      try { 
       socket.close(); 
      } catch (IOException e) { 
       log("Couldn't close a socket, what's going on?"); 
      } 
     } 
    } 
} 

Gibt es eine Alternative zum Beispiel nicht blockierender Modus?

Bei nicht blockierenden Socket-Kanälen muss sich der Server-Socket beim Selektor registrieren, um bestimmte Operationen auszuführen. Standardmäßig ist ein Server-Socket-Kanal ein blockierender Kanal. Um es zu einem nicht blockierenden Kanal zu machen, setze folgendes.

channel.configureBlocking(false); 

Der Non-Blocking-Server-Programm wie ...

InetAddress hostIPAddress = InetAddress.getByName("localhost"); 
int port = 19000; 
Selector selector = Selector.open(); 
ServerSocketChannel channel = ServerSocketChannel.open(); 
channel.configureBlocking(false); 
channel.socket().bind(new InetSocketAddress(hostIPAddress, port)); 
channel.register(selector, SelectionKey.OP_ACCEPT); 

while (true) { 
    Set keys = selector.selectedKeys(); 
    ... 
} 

Das non-blocking-Client-Programm aussehen wird, aussehen wird ...

InetAddress serverIPAddress = InetAddress.getByName("localhost"); 
InetSocketAddress serverAddress = new InetSocketAddress(
    serverIPAddress, 19000); 
Selector selector = Selector.open(); 
SocketChannel channel = SocketChannel.open(); 
channel.configureBlocking(false); 
channel.connect(serverAddress); 
int operations = SelectionKey.OP_CONNECT | SelectionKey.OP_READ 
    | SelectionKey.OP_WRITE; 
channel.register(selector, operations); 

while (true) { 
    if (selector.select() > 0) { 
    Set keys = selector.selectedKeys(); 
    ... 
    } 
} 
channel.close(); 
0

Sie könnten einen Thread-Pool erstellen und die Clientsocket als neue Aufgabe an den Threadpool

Socket clientSocket = serverSocket.accept(); 
threadPool.submit(new ClientTask(clientSocket)); 

Sie können mehrere Implementierungen für Multi-Threaded-Server im Internet, lesen Sie in diesem one

Verwandte Themen