# ServerSocket prinzipielle Frage



## akira (20. Jun 2004)

Hallo,

ich habe vor, ein kleines Multiplayer-Onlinespiel auf der Basis von Applets als Clients und einem Server zu realisieren. 
In Java bin ich eigentlich recht fit, jedoch habe ich noch nie mit Sockets gearbeitet. Wie ich einen ServerSocket öffne ist mir klar, auch das die Methode .accept() auf eingehende Requests wartet. Die Methode liefert nun einen Socket, über den per Input-/OutputStream gelesen bzw. geschrieben werden kann. Für EINEN Client ist das soweit alles klar. 

Ich möchte jedoch natürlich mehrere Clients gleichzeitig mit dem Server verbinden. Ich habe in diesem Zusammenhang gelesen, daß man nun im Server für jeden Socket, den man per accept erhalten hat, einen neuen Thread öffnet.

Nun zu meinen Fragen:

1. Können also mehrere Sockets auf einem Port zur gleichen Zeit laufen?
2. Bleibt ein Socket während der gesamten Kommunikation mit einem Client bis zur Abmeldung offen, oder wird für jeden Request ein neuer geöfnet?

Ich hoffe, ihr könnt mir da bei meinem Verständnisproblem helfen.


----------



## Roar (20. Jun 2004)

ok.
also 1. ja sicher kann man gleichzeiotig mehrer sockets auf einem port bedienen, wie du schon gesagt hast mit multithreading
2. das kommt drauf an. bei HTTP zum beispiel läufts so ab dass der client eine nrequest shcickt und der server die entsprechende datei zurückschickt. danach wird der socket direkt geschlosssen. Bei FTP bleibt der socket längere zeit offen und shcließt sich irgendwann automatisch per timeout wenn über eine bestimmte zeit kein kommando gesendet wurde.

Hier ein kleines bneispiel aus meinem http server:


```
//...

ServerSocket httpd = new ServerSocket(80); // ServerSocket initalisiere
while (true) {
Socket socket = httpd.accept();
ClientThread clientThread = new ClientThread(socket); // neuen thread für request
clientThread.start();
}

//...

import java.io.*;
import java.util.*;
import java.net.*;
import net.roarsoftware.net.HTTPRequest; // parst den HTTP request

class ClientThread extends Thread implements net.roarsoftware.net.HTTPConstants {

private Socket s; // socket
private InputStream is; // io streams...
private PrintStream ps;
//...
public ClientThread(Socket s) throws IOException {
this.s = s;
this.is = s.getInputStream();
this.ps = new PrintStream(s.getOutputStream());
//...

public void run() {
java.awt.Toolkit.getDefaultToolkit().beep();
StringBuffer sb = new StringBuffer();
try{ 
// read request
int c;
while ((c = is.read()) != -1) {
if (c == '\n') {
         if (sb.substring(sb.length()-3).equals("\r\n\r")) {
           break;
         }
}
sb.append((char)c);
}
} catch(IOException ex) {
httpError(500, "Internal Server Error", "Error occured on reading Request. " + ex.getMessage() ); // httpError sendet eine fehlerseite an den client
}
String[] lines = HTTPRequest.parseRequest(sb.toString());
//....
// pars den hhtp request und antworte entsprechen

private void httpError(int code, String type, String description) { // beispiel um daten an die nclient zurückzusenden
ps.print("HTTP/1.0 " + code + " " + type + "\r\n");
ps.print("Content-type: text/html\r\n\r\n");
ps.println("<html>");
ps.println("<head>");
ps.println("<title>" + code +" " + type + "</title>");
ps.println("</head>");
ps.println("<body>");
ps.println("<h1>" + type + "</h1>");
ps.println("

" + description);
ps.println("<hr>[i]Requestor 8-D 1.0 Server at " + host + " Port " + port + "[/i]");
ps.println("</body>");
ps.println("</html>");
}
```


----------



## akira (20. Jun 2004)

Danke, für Deine schnelle Antwort.

Am idealsten für mich wäre es, wenn die Socketverbindung vom einloggen bis zum ausloggen (das einige Stunden dauern kann) andauern würde. Wäre das also möglich, oder gibt es irgendwann einen timeout?


----------



## Roar (20. Jun 2004)

du kannst den timeout beim socket setzen. eigentlich sollte die verbindung solange stehen bis entweder der client oder der server den socket schließt. einfach ausprobieren.


----------



## Dante (20. Jun 2004)

Hi,

der Serversocket belegt den Port an den er gebunden wird, wenn nun eine neue Verbindung auf diesem Port eingeht, wir diese vom Betriebssystem auf einen anderen freien Port umgeleitet, meist in der fünfstelligen Region. Somit läuft alle weitere Kommunikation mit dem Socket den accept() zurückgegeben hat auf einem ganz anderen Port. Wenn nun der ServerSocket zB. durch eine Schleife wieder in accept() ankommt, kann er weitere Verbindungen annehmen die dann analog wieder auf einen anderen Port umgeleitet werden.

Wenn du den Socket nicht schliesst und du ihm keinen timeout (Socket.setSOTimeout()) zugewiesen hast bleibt der ewig offen.


----------



## akira (20. Jun 2004)

Vielen Dank für eure Antworten, jetzt ist mir die Sache schon viel klarer.

Ich habe mir mittleiweile auch schon das Grundgerüst des Servers gschrieben und werde das
jetzt mal mit ein paar Clients testen..


----------

