App installieren
How to install the app on iOS
Follow along with the video below to see how to install our site as a web app on your home screen.
Anmerkung: This feature may not be available in some browsers.
Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden.
Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Java: Client schickt, Server empfängt nur einen Teil
- Ersteller MAjbO
- Erstellt am
Hi
Ich beschäftige mich zum ersten mal mit Sockets und habe ein für mich nicht nachvollziehbares Problem.
Zum Verständnis das Konzept: Der Client schickt dem Server mehrere serialisierte Objekte. Diese sollen dann auf dem Server weiterverarbeitet werden, zu Testzwecken wird aber einfach ein String aus dem Objekt ausgegeben.
Der Fehler ist nun, dass der nicht alle vom Client verschickten Objekte auch beim Server ankommen. Als Workaround habe ich rausgefunden, dass dies nicht passiert, wenn ich nach jedem gesendeten Objekt Thread.sleep(200); aufrufe, aber das kann ja keine Lösung sein.
Vereinfachter Code (ohne Error-Handling) vom Client (messages ist eine generische ArrayList mit den LogMessage-Objekten die ich übertragen möchte).
Server:
Sieht jemand, was ich falsch mache?
Grüsse
MAjbO
Ich beschäftige mich zum ersten mal mit Sockets und habe ein für mich nicht nachvollziehbares Problem.
Zum Verständnis das Konzept: Der Client schickt dem Server mehrere serialisierte Objekte. Diese sollen dann auf dem Server weiterverarbeitet werden, zu Testzwecken wird aber einfach ein String aus dem Objekt ausgegeben.
Der Fehler ist nun, dass der nicht alle vom Client verschickten Objekte auch beim Server ankommen. Als Workaround habe ich rausgefunden, dass dies nicht passiert, wenn ich nach jedem gesendeten Objekt Thread.sleep(200); aufrufe, aber das kann ja keine Lösung sein.
Vereinfachter Code (ohne Error-Handling) vom Client (messages ist eine generische ArrayList mit den LogMessage-Objekten die ich übertragen möchte).
PHP:
Socket socket = null;
socket = new Socket(server_host, port);
OutputStream oStream = socket.getOutputStream();
ObjectOutputStream ooStream = null;
for (int i=0; i<messages.size(); i++){
ooStream = new ObjectOutputStream(oStream);
msg = messages.get(0);
ooStream.writeObject(msg);
messages.remove(0);
System.err.println(msg.getMsg() + " übertragen");
Thread.sleep(200);
}
Server:
PHP:
while (true)
{
// listen for and accept a client connection to serverSocket
Socket sock = this.serverSocket.accept();
InputStream iStream = sock.getInputStream();
ObjectInputStream oiStream = new ObjectInputStream(iStream);
try {
this.logMessage = (LogMessage) oiStream.readObject();
} catch (ClassNotFoundException ex) {
Logger.getLogger(TCPServer.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(this.logMessage.getMsg());
iStream.close();
}
Sieht jemand, was ich falsch mache?
Grüsse
MAjbO
The G
Lt. Commander
- Mitglied seit
- 22.04.2008
- Beiträge
- 128
- Renomée
- 2
- Standort
- Das schöne Allgäu
- Prozessor
- AMD Phenom II 965 C3 @ 3,8GHz
- Mainboard
- MSI 790GX-G65
- Kühlung
- EKL Nordwand
- Grafikprozessor
- Sapphire 3870
- Display
- LG W2442PA @ 1920x1080
- HDD
- Samsung Spinpoint F1 & F3
- Soundkarte
- Creative Sound Blaster X-FI Titanium
- Gehäuse
- Lancool K62
- Netzteil
- Arctic Cooling Fusion 550R
- Betriebssystem
- Windows 7 Ultimate 64bit
- Webbrowser
- Firefox
Eines vorneweg: Bin in Java etwas aus der Übung Zuerst wunder ich mich mal über das Vorgehen an sich. Auf Clientseite baust du eine Verbindung auf über die für jedes einzelne Objekt ein eigener ObjectStream gelegt wird, da würde einer reichen. Auf Serverseite rufst du in jedem Schleifenaufruf serverSocket.accept, was eigentlich heißen müsste das der Server nach jedem empfangenen Objekt die Verbindung neu aufbaut. Wundert mich ehrlich dass das überhaupt funktioniert
Zum eigentlichen Problem: Wenn du etwas in den ObjectStream schiebst schubst der das nicht unbedingt direkt an die Verbindung weiter sondern kann es auch zwischenspeichern. Ähnlich der OuputStream an sich. Ein flush() "spült" alles sofort raus.
Also statt:
Das hier:
Hoffe das hilft. Würde aber wie geschrieben das Vorgehen insgesamt nochmal überdenken.
Zum eigentlichen Problem: Wenn du etwas in den ObjectStream schiebst schubst der das nicht unbedingt direkt an die Verbindung weiter sondern kann es auch zwischenspeichern. Ähnlich der OuputStream an sich. Ein flush() "spült" alles sofort raus.
Also statt:
Code:
Thread.sleep(200);
Code:
ooStream.flush();
oStream.flush(); //Nicht sicher ob das nötig ist
Hoffe das hilft. Würde aber wie geschrieben das Vorgehen insgesamt nochmal überdenken.
Wie "The G" schon geschrieben hat, ist es erstaunlich, dass das ganze überhaupt funktioniert
Du schreibst mehrere Objekte in eine Verbindung, liest aber auf der Server-Seite nur das erste Objekt aus.
iStream.close() verwirft dann wohl die restlichen bereits empfangenen Objekte.
Wenn du über oiStrea.readObject() loopst sollte es klappen.
Entweder auf beiden Seiten ein Objekt pro Verbindung, oder nur eine Verbindung und alle Objekte darüber versenden.
Du schreibst mehrere Objekte in eine Verbindung, liest aber auf der Server-Seite nur das erste Objekt aus.
iStream.close() verwirft dann wohl die restlichen bereits empfangenen Objekte.
Wenn du über oiStrea.readObject() loopst sollte es klappen.
Entweder auf beiden Seiten ein Objekt pro Verbindung, oder nur eine Verbindung und alle Objekte darüber versenden.
Zuletzt bearbeitet:
The G
Lt. Commander
- Mitglied seit
- 22.04.2008
- Beiträge
- 128
- Renomée
- 2
- Standort
- Das schöne Allgäu
- Prozessor
- AMD Phenom II 965 C3 @ 3,8GHz
- Mainboard
- MSI 790GX-G65
- Kühlung
- EKL Nordwand
- Grafikprozessor
- Sapphire 3870
- Display
- LG W2442PA @ 1920x1080
- HDD
- Samsung Spinpoint F1 & F3
- Soundkarte
- Creative Sound Blaster X-FI Titanium
- Gehäuse
- Lancool K62
- Netzteil
- Arctic Cooling Fusion 550R
- Betriebssystem
- Windows 7 Ultimate 64bit
- Webbrowser
- Firefox
Wenn das die Ursache für das Probleme wäre dürfte aber der Sleep nicht als Workaround funktionieren. Sonst würde ich das genauso sehen. Darum wundere ich mich auch etwas
The G
Lt. Commander
- Mitglied seit
- 22.04.2008
- Beiträge
- 128
- Renomée
- 2
- Standort
- Das schöne Allgäu
- Prozessor
- AMD Phenom II 965 C3 @ 3,8GHz
- Mainboard
- MSI 790GX-G65
- Kühlung
- EKL Nordwand
- Grafikprozessor
- Sapphire 3870
- Display
- LG W2442PA @ 1920x1080
- HDD
- Samsung Spinpoint F1 & F3
- Soundkarte
- Creative Sound Blaster X-FI Titanium
- Gehäuse
- Lancool K62
- Netzteil
- Arctic Cooling Fusion 550R
- Betriebssystem
- Windows 7 Ultimate 64bit
- Webbrowser
- Firefox
Wäre ne schlüssige Erklärung. Der Client müsste ungefragt versuchen die getrennte Verbindung neu aufzubauen. Würde auch den Sleep-Workaround erklären, da der Client in der Zeit die Möglichkeit hat die beendete Verbindung zu registrieren und nicht das nächste Objekt in die tote Leitung pumpt. Wobei ich bei TCP eigentlich erwarten würde das da irgendwo ne Exception fliegt.
Erstmal danke euch beiden für die Hinweise, werde nachher mal versuchen, diese Umzusetzen.
Wie könnte das loopen über readObject aussehen? Dafür fehlt mir eine Abbruchbedingung. Wäre es vielleicht sinnvoll, erst mal einen int mit der Anzahl der Objekte zu schicken um anschliessen genau zu wissen, wie oft man readObject aufrufen darf?
Wenn du über oiStrea.readObject() loopst sollte es klappen.
Entweder auf beiden Seiten ein Objekt pro Verbindung, oder nur eine Verbindung und alle Objekte darüber versenden.
Wie könnte das loopen über readObject aussehen? Dafür fehlt mir eine Abbruchbedingung. Wäre es vielleicht sinnvoll, erst mal einen int mit der Anzahl der Objekte zu schicken um anschliessen genau zu wissen, wie oft man readObject aufrufen darf?
The G
Lt. Commander
- Mitglied seit
- 22.04.2008
- Beiträge
- 128
- Renomée
- 2
- Standort
- Das schöne Allgäu
- Prozessor
- AMD Phenom II 965 C3 @ 3,8GHz
- Mainboard
- MSI 790GX-G65
- Kühlung
- EKL Nordwand
- Grafikprozessor
- Sapphire 3870
- Display
- LG W2442PA @ 1920x1080
- HDD
- Samsung Spinpoint F1 & F3
- Soundkarte
- Creative Sound Blaster X-FI Titanium
- Gehäuse
- Lancool K62
- Netzteil
- Arctic Cooling Fusion 550R
- Betriebssystem
- Windows 7 Ultimate 64bit
- Webbrowser
- Firefox
Du könntest statt aller Einträge einzeln einfach die ArrayList selbst schicken. Ist ja auch nur ein Objekt. Damit sparst du dir die Frage nach der Anzahl der enthaltenen Objekte. Außer Java hat Probleme mit Generics im ObjectStream
AFAIR blockt readObject() bis ein neues Objekt komplett eingelesen wurde.
Mögliche Lösungen für loop:
1. while(true/_bGo) und das ganze in einen eigenen thread auslagern, den du irgendwann killst/abbrichst.
2. mit available() prüfen ob noch zusätzliche Daten vorhanden sind. Da hast du allerdings auch wieder ein Timing-Problem.
3. vielleicht bricht der read ab, wenn du die Verbindung auf der Client-Seite schliesst...
4. Wie schon vorgeschlagen ein Objekt pro Verbindung (Message oder Array)
5. Sende ein "Ende"-Objekt über das Netz um die Kommunikation zu beenden.
Gibt sicher noch andere Möglichkeiten
Mögliche Lösungen für loop:
1. while(true/_bGo) und das ganze in einen eigenen thread auslagern, den du irgendwann killst/abbrichst.
2. mit available() prüfen ob noch zusätzliche Daten vorhanden sind. Da hast du allerdings auch wieder ein Timing-Problem.
3. vielleicht bricht der read ab, wenn du die Verbindung auf der Client-Seite schliesst...
4. Wie schon vorgeschlagen ein Objekt pro Verbindung (Message oder Array)
5. Sende ein "Ende"-Objekt über das Netz um die Kommunikation zu beenden.
Gibt sicher noch andere Möglichkeiten
BoMbY
Grand Admiral Special
- Mitglied seit
- 22.11.2001
- Beiträge
- 7.468
- Renomée
- 293
- Standort
- Aachen
- Prozessor
- Ryzen 3700X
- Mainboard
- Gigabyte X570 Aorus Elite
- Kühlung
- Noctua NH-U12A
- Speicher
- 2x16 GB, G.Skill F4-3200C14D-32GVK @ 3600 16-16-16-32-48-1T
- Grafikprozessor
- RX 5700 XTX
- Display
- Samsung CHG70, 32", 2560x1440@144Hz, FreeSync2
- SSD
- AORUS NVMe Gen4 SSD 2TB, Samsung 960 EVO 1TB, Samsung 840 EVO 1TB, Samsung 850 EVO 512GB
- Optisches Laufwerk
- Sony BD-5300S-0B (eSATA)
- Gehäuse
- Phanteks Evolv ATX
- Netzteil
- Enermax Platimax D.F. 750W
- Betriebssystem
- Windows 10
- Webbrowser
- Firefox
Ja, also gibt's bei Java keine Async-Sockets?
Das Problem sieht doch schematisch so aus:
1. Client sendet
2. Server empfängt
3. Server startet Verarbeitung
4. Client sendet
5. Server beendet Verarbeitung
6. Server ist wieder empfangsbereit
Das heißt der Server ist noch nicht soweit etwas zu empfangen, während der Client schon sendet. Bei C# kenne ich das so, dass der Server die ganze Zeit auf empfangen steht, und dann halt asynchron einen Thread für jeden empfangenen Block startet.
.
EDIT :
.
Also vielleicht kann man ja irgendwie so arbeiten (Pseudocode):
Das Problem sieht doch schematisch so aus:
1. Client sendet
2. Server empfängt
3. Server startet Verarbeitung
4. Client sendet
5. Server beendet Verarbeitung
6. Server ist wieder empfangsbereit
Das heißt der Server ist noch nicht soweit etwas zu empfangen, während der Client schon sendet. Bei C# kenne ich das so, dass der Server die ganze Zeit auf empfangen steht, und dann halt asynchron einen Thread für jeden empfangenen Block startet.
.
EDIT :
.
Also vielleicht kann man ja irgendwie so arbeiten (Pseudocode):
Code:
while (true)
{
// listen for and accept a client connection to serverSocket
Socket sock = this.serverSocket.accept();
new Thread(get_data(sock)); // Verbindung an Thread auslagern
}
void get_data(Socket sock)
{
InputStream iStream = sock.getInputStream();
ObjectInputStream oiStream = new ObjectInputStream(iStream);
while ( sock.isOpen )
{
try {
this.logMessage = (LogMessage) oiStream.readObject();
} catch (ClassNotFoundException ex) {
Logger.getLogger(TCPServer.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(this.logMessage.getMsg());
}
iStream.close();
}
Ähnliche Themen
- Antworten
- 3
- Aufrufe
- 8K
- Antworten
- 16
- Aufrufe
- 7K
- Antworten
- 0
- Aufrufe
- 142K