Hallo Leute.
Erstmal OT: vllt werden sich ein paar fragen, was mit meinem 3d projekt ist, aber das war kein projekt… ich hab nur versucht mich da ein bisschen
reinzulernen und das hab ich ja auch getan - das was ich bisher gemacht hab hab ich auch verstanden und gelernt.
Nun habe ich mit Java Sockets und dem Server Client prinzip angefangen, einerseits weil das schon lange auf meiner warteschlange steht und andererseits
weil mein Lehrer, der weiß das ich ein bisschen zu weit für die ef bin, das für eine gute sache für mich hielt ^^
Naja zu meinem ersten Problem: Die Kommunikation zwischen Server und einem clienthab ich bereits hinbekommen, auch wenn bislang nur über strings.
Ich hab das im grunde folgender maßen gemacht:
der server läuft in einer endlosschleife, speichert die ausgabe von bufferedReader.readLine() in einem string, guckt ob der “stop” ist, (um dann abzubrechen),
gibt ansonsten die erhaltene nachricht aus, und läuft wieder nach oben.
Der Client schickt bislang einfach nur 3 testnachrichten mit (outputstream) jeweils printWriter.print(irendwas), die kommen auch an, mit “stop” wird richtig beendet.
ABER: wenn eine nachricht geschickt wurde, bleibt der server natürlich bei reader.readLine() hängen - wartet also bis irgendetwas gesendet wird. ist ja logisch.
Das ganze sieht so aus:
System.out.println("#Server [connection_start]: STARTING");
try{
loop:
while(true){
String input = s.readLine();
if(input.equals("stop")){
break loop;
}
else{
System.out.println("#Server [new_message]: " + input + " [" + s.getLocalIp());
}
}
System.out.println("#Server [connection_end]: EXIT");
}
catch(Exception e){
e.printStackTrace();
}```
Für einen Client mag das ja klappen, weil der ja der einzige ist der etwas senden kann.
Aber wenn ich nun mehrere clients haben will, die sich mit diesem server verbinden können sollen?
Ich dachte erstmal an folgendes:
```System.out.println("#Server [connection_start]: STARTING");
try{
loop:
while(true){
for(ClientUser s : clientSockets){
String input = s.readLine();
if(input.equals("stop")){
break loop;
}
else{
System.out.println("#Server [new_message]: " + input + " [" + s.getLocalIp());
}
}
}
System.out.println("#Server [connection_end]: EXIT");
}
catch(Exception e){
e.printStackTrace();
}```
also das selbe, nur eben mit der for loop - die durch alle verbundenen sockets läuft. diese sockets werden einfach so aufgefüllt:
```public synchronized void run(){
while(true){
try{
Socket incoming = serverSocket.accept();
clientSockets.add(new ClientUser(incoming));
}
catch(Exception e){
e.printStackTrace();
}
}
}```
das klappt auch, die sockets verbinden sich und werden in der array list abgelegt. aber die for loop geht natürlich gar nicht. denn sobald ein client nichts sendet, geht der
server ja trozdem zu readLine() und wartet auf nen signal eingang. Das Problem ist, if(readLine() != null) geht auch nicht, denn wenn nichts gesendet wird, ist readLine() nicht null
sondern eben ein "ich warte jetzt so lange bis was kommt".
Wie soll ich denn bitte prüfen, ob etwas kommt, wenn ich das nur machen kann in dem ich etwas senden, aber nichts mehr senden will? o.O
ich dachte vllt an eine for loop im client die zum beispiel "ichsendenichts" sendet, und dadurch der server ads einfach ignoriert. aber das ist doch totaler schwachsinn, allein wegem dem
traffic der dabei erzeugt wird.
Wie mach ich das also? Wie prüfe ich ob da nichts ankommt vom socket?
Vielen Dank!
Hier der ganze Code:
de.skysoldier.chat
[spoiler]
[SPOILER=ChatServer.java]```package de.skysoldier.chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class ChatServer implements Runnable {
private Thread thread;
private ServerSocket serverSocket;
private UserManager userManager;
private ArrayList<ClientUser> clientSockets;
public ChatServer(int port){
thread = new Thread(this);
try{
serverSocket = new ServerSocket(port);
}
catch(Exception e){
e.printStackTrace();
}
clientSockets = new ArrayList<>();
userManager = new UserManager();
thread.start();
}
public String getLocalPort(){
return serverSocket.getLocalPort() + "";
}
public String getLocalIp(){
try{
return InetAddress.getLocalHost().getHostAddress();
}
catch(Exception e){
e.printStackTrace();
return null;
}
}
public void run(){
System.out.println("#Server [connection_start]: STARTING");
try{
loop:
while(true){
for(ClientUser s : clientSockets){
String input = s.readLine();
if(input.equals("stop")){
break loop;
}
else{
System.out.println("#Server [new_message]: " + input + " [" + s.getLocalIp());
}
}
}
System.out.println("#Server [connection_end]: EXIT");
}
catch(Exception e){
e.printStackTrace();
}
}
private class UserManager implements Runnable {
Thread t;
private UserManager(){
t = new Thread(this);
t.start();
}
public synchronized void run(){
while(true){
try{
Socket incoming = serverSocket.accept();
clientSockets.add(new ClientUser(incoming));
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
private class ClientUser {
private BufferedReader messageReader;
private Socket clientSocket;
private ClientUser(Socket clientSocket){
try{
messageReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch(Exception e){
e.printStackTrace();
}
this.clientSocket = clientSocket;
}
public String readLine(){
try{
return messageReader.readLine();
}
catch(Exception e){
e.printStackTrace();
return null;
}
}
public String getLocalIp(){
return clientSocket.getInetAddress().getHostAddress();
}
}
}```[/spoiler]
ServerGui.java
[spoiler]```package de.skysoldier.chat;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ServerGui {
JFrame f;
ChatServer server;
public ServerGui(){
init();
buildGui();
}
private void init(){
server = new ChatServer(5151);
}
private void buildGui(){
f = new JFrame();
f.setAlwaysOnTop(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400, 300);
f.setLayout(new BorderLayout());
f.add(new JLabel(server.getLocalIp() + " : " + server.getLocalPort()));
f.setVisible(true);
}
public static void main(String[] args) {
new ServerGui();
}
}```[/spoiler]
ChatClient.java
[spoiler]```package de.skysoldier.chat;
import java.io.PrintWriter;
import java.net.Socket;
public class ChatClient {
Socket s;
PrintWriter writer;
public ChatClient(int port){
try{
s = new Socket("192.168.0.119", port);
writer = new PrintWriter(s.getOutputStream(), true);
}
catch(Exception e){
e.printStackTrace();
}
}
public void send(String s){
try{
writer.print(s + "
");
writer.flush();
}
catch(Exception e){
e.printStackTrace();
}
}
}
```[/spoiler]
ChatGui
[spoiler]```package de.skysoldier.chat;
import java.awt.BorderLayout;
import javax.swing.JFrame;
public class ClientGui {
JFrame f;
ChatClient client;
public ClientGui(){
init();
buildGui();
}
private void init(){
client = new ChatClient(5151);
}
private void buildGui(){
f = new JFrame();
f.setAlwaysOnTop(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400, 300);
f.setLocation(500, 0);
f.setLayout(new BorderLayout());
f.setVisible(true);
client.send("test515151:::5151");
client.send("ab zu bio");
client.send("stC");
}
public static void main(String[] args) {
new ClientGui();
}
}```[/spoiler]
[/SPOILER]