import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class ClientTest {
private DataOutputStream streamOut = null;
long counter = 0;
public static void main(String[] args) {
new ClientTest(3443);
}
public ClientTest(int port) {
Socket serverConnection = null;
try {
SocketAddress addr = new InetSocketAddress( "localhost", 3443 );
serverConnection = new Socket();
serverConnection.connect( addr, 100 );
streamOut = new DataOutputStream(serverConnection.getOutputStream());
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
counter += System.nanoTime();
if (counter > 10000000) {
counter = 0;
streamOut.writeUTF("i:");
}
Thread.sleep(1);
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
});
t.start();
} catch (SocketException ex) {
ex.printStackTrace();
} catch (UnknownHostException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
serverConnection.close();
} catch (IOException ex) {
}
}
}
}
Aus irgendeinem Grund(der mir als Socket Anfänger nicht auffällt) kommt diese Ausgabe:
Server:
wait for new Client's
wait for new Client's
//Und dann in Endlosschleife:
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:337)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at badTestings.socketTests.ServerTest$ClientThread.run(ServerTest.java:99)
Client:
//In Endlosschleife:
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:337)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at badTestings.socketTests.ServerTest$ClientThread.run(ServerTest.java:99)
Wäre ultra freundlich wenn sich jemand den Code mal angucken könnte! Ich stehe nämlich völlig auf dem Schlauch!!!
:verzweifel: :verzweifel: :verzweifel:
:wein:
wenn der Server, der checkForNewClients-Thread, eine Verbindung akzeptiert, gibt er diese an einen Thread dafür ab,
Millesekunden später ist er im finally und schließt die Verbindung,
das kann es ja nicht sein, der checkForNewClients-Thread darf die Verbindung nicht schließen,
dass muss er dem Thread für diese Verbindung überlassen, z.B. am Ende von dessen run()-Methode
beim Client ähnliches Problem
übrigens ist die main-Methode selber ein Thread,
wenn dort nichts anderes an Code kommt, dann könnte der main-Thread ja auch irgendwas machen,
der checkForNewClients-Thread beim Server ist unnötig,
beim Client ist der eine Thread t im Moment auch unnötig,
aber schadet beides auch nicht viel, nur Code etwas unübersichtlich
jetzt hat der Server seine endlos Exception geändert:
java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:340)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at socketTests.ServerTest$ClientThread.run(ServerTest.java:89)
ich habe ein Testprogramm ohne jedes close zusammengebaut (langfristig natürlich keine Lösung, aber ein laufender Anfang),
eine main startet Server + Client (hier bringen deine extra-Threads Vorteile)
Code ein wenig geändert, alle 0.6 sec wird eine sich erhöhende Zahl gesendet
Ausgabe:
wait for new Client's
wait for new Client's
i:1
i:2
i:3
i:4
i:5
i:6
i:7
...
public class Test {
public static void main(String[] args) throws Exception {
new ServerTest2(3443);
Thread.sleep(400);
new ClientTest2(3443);
}
}
class ServerTest2 {
ServerSocket serverSocket = null;
ArrayList<ClientThread> clients = new ArrayList<ClientThread>();
public void sendMsgToAll(String s) {
for (ClientThread ct : clients) {
try {
ct.sendToClient(s);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public ServerTest2(int port) {
try {
serverSocket = new ServerSocket(port);
} catch (IOException ex) {
ex.printStackTrace();
}
Thread checkForNewClients = new Thread(new Runnable() {
@Override
public void run() {
Socket newClientConnection = null;
while (true) {
System.out.println("wait for new Client's");
try {
newClientConnection = serverSocket.accept();
ClientThread ct = new ClientThread(newClientConnection);
ct.start();
clients.add(ct);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
checkForNewClients.start();
}
private class ClientThread extends Thread {
String idName;
Socket clientConnection;
DataInputStream inputStream;
DataOutputStream outputStream;
public ClientThread(Socket clientConn) {
clientConnection = clientConn;
try {
inputStream = new DataInputStream(new BufferedInputStream(
clientConnection.getInputStream()));
outputStream = new DataOutputStream(new BufferedOutputStream(
clientConnection.getOutputStream()));
} catch (IOException ex) {
}
}
public void sendToClient(String s) throws IOException {
outputStream.writeChars(s);
}
@Override
public void run() {
while (true) {
try {
String s = inputStream.readUTF();
System.out.println(s);
sendMsgToAll(s);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
}
class ClientTest2 {
private DataOutputStream streamOut = null;
long counter = 0;
public ClientTest2(int port) {
Socket serverConnection = null;
try {
SocketAddress addr = new InetSocketAddress("localhost", 3443);
serverConnection = new Socket();
serverConnection.connect(addr, 100);
streamOut = new DataOutputStream(serverConnection.getOutputStream());
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
counter++;
streamOut.writeUTF("i:" + counter);
Thread.sleep(600);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
t.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Ahh, danke der Code funktioniert, aber was genau hast du geändert?
Ich sehe nur den teil im Thread der ClientTest2 und wahrscheinlich den Wald vor lauter Bäumen nicht…
Ok, du hast also das finally am Ende des Client Thread’s auch noch entfernt…
Gut, aber korrigier mich:
Finnally wird doch erst am Ende oder wenn eine Exception aufgerufen wird ausgelöst…
EDIT: verdammt mein Thread hat mir hier wohl ein Bein gestellt
Danke!!
Ich poste hier vielleicht noch mein Endergebnis, wenn es nicht zu stümperhaft ist :crowd:
wie gesagt war beim Server + Client im ersten Posting die Situation gleich, in beiden wurde sofort geschlossen,
es wird nicht gewartet, bis der gestartete Thread zu Ende ist, das widerspricht ja auch dem Sinn des Starten eines Threads
ein Buffer buffert, das ist seine Grundfunktion, sendet nicht sofort, sondern erst wenn z.B. 8192 Bytes zusammenkommen,
flush() kann das Senden erzwingen, Standard-Befehl in diesem Bereich
(sinnvoll wäre auch, nach einer gewissen Zeit zu senden, maximal einmal pro Sekunde während zig kleine Kommandos pro Sekunde ankommen,
hier nicht der Fall, nur Steuerung über Anzahl Bytes)
ein einfaches 10 Zeile-Programm kann sowas testen, viele Klassen mit viel unnötigen Code verschleiern es nur,
irgendwann wäre ich aber auch dazu gekommen
[QUOTE=SlaterB]
ein einfaches 10 Zeile-Programm kann sowas testen, viele Klassen mit viel unnötigen Code verschleiern es nur,
irgendwann wäre ich aber auch dazu gekommen[/QUOTE]
Ich habe es auch nur im direkten Vergleich bemerkt…
Naja ich habe jetzt die Output und InputStream’s in ObjectOutput und ObjectInputStream’s geändert und schon EOFException beim zurücksenden! Fällt dir da spontan ein Grund ein?
Ich mach erstmal mein Test-Programm mit dem String hin und her senden fertig, aber ich möchte später auch Objekte senden!!! Nur ein erster Test lieferte halt das…
Beim hin und zurücksenden(es wurden weiter Strings gesendet nur eben über die Methode writeObject(…); ) kam dieselbe Ausgabe, nur beim berüchtigen Server to Client senden kam wieder dieser Fehler!
EOFException klingt naturgemäß genauso wie schon Posting #3, kann wieder eine Frage von zu frühen Schließen auf einer Seite sein,
wenn mir nicht davon abgeraten wäre, dich für so ‚dumm‘ zu halten, das wieder zu machen
vielleicht passen die Streams auch nicht zusammen, auf einer Seite ObjectInputStream,
auf der anderen nicht ObjectOutputStream sondern ein anderer,
nach deinem Posting eigentlich auch ausgeschlossen
[QUOTE=SlaterB]
es hilft nur Code[/QUOTE]
Ja, oder nachdenken auch hier war wieder flush(); nötig…
Ich glaub ich mach den Fehler noch 3 Mal und dann hör ich auf