Bidirectional Socketverbindung

Fohnbit

Top Contributor
Hallo Gemeinde,

ich habe mir für einen Server eine Socketanbindung geschrieben. Das Empfangen läuft in einem eigenen Thread und gibt die Daten ans Main Programm weiter. Zum senden wird einfach eine andere Socketverbindung zum Server aufgebaut und wieder beendet.

Nun habe ich einen anderen Server wo ich das selbe benötige, jedoch läßt dieser nur eine Socketverbindung zu. So ist der Server belegt wenn ich "horche" und kann keine weiteren Befehle senden.
Wie kann ich meinen Code ändern (welcher vom Main Class aheufgerufen wird) damit dieser bidriectional ist?

Java:
public class Listener extends Thread

{    
	
    public Listener(Commend SC, String IP, int Port) {
        this.SC = SC;
        this.IP = IP;
        this.Port = Port;
    }

	private Socket clientSocket;
	private DataOutputStream outToServer;
	private BufferedReader inFromServer;
	private Boolean connected; 
	private Commend SC;
	private String IP;
	private int Port;
	
	
	String answer;
	
		public void run() {
			
		try {
			clientSocket = new Socket(IP, Port);
			outToServer = new DataOutputStream(clientSocket.getOutputStream());
			inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
			// outToServer.writeBytes("listen 1\n");
			// answer = inFromServer.readLine();
	    	// SC.setAnswer(answer);
			//outToServer.writeBytes("00:04:20:07:3a:b7 status\n");
			// answer = inFromServer.readLine();
	    	//  SC.setAnswer(answer);
			connected = true;
			 while(connected){
		    	  answer = inFromServer.readLine();
		    	  SC.setAnswer(answer);
			 }
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}

Vielen Dank!
 

Michael...

Top Contributor
Das Empfangen und Senden muss in jeweils einem eigenen Thread passieren. Momentan wartest Du ja bis eine Zeile eingelesen wurde und antwortest dann darauf.
 

Fohnbit

Top Contributor
Hallo,

ja, es wird vom Main aus gesendet.Anbei nochmal genauerer Code:

Verbindung aufbauen und halten
Java:
	private void connect(){
		sendOut("connected","value","connecting ...");
    	try {
    		String IP = get("serverip");
    		int Port = getInt("port",17000);
    		clientSocket = null;
			clientSocket = new Socket(IP,Port );
			outToServer = new DataOutputStream(clientSocket.getOutputStream());
			inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	if(clientSocket.isConnected()){
		if(listen == null){
			listen = new Listener(this);
			listen.start();
			connectet = true;
			sendOut("connected","value","connected");
					
			}
	}
	}

Listerner:
Java:
public class Listener extends Thread

{    
	
    public Listener(Commend SC) {
        this.SC = SC;
    }

	
	private Commend SC;

	int answer;
	
		public void run() {
			
		try {
		
			String EoL = null;
			
			 while(SC.clientSocket.isConnected()){
		    	  answer = SC.inFromServer.read();
		    	  if(answer == 255){
		    		 SC.setAnswer(EoL);
		    		 EoL = null;
		    	  }
		    	  else {
		    		  EoL =  EoL + String.valueOf(answer)+",";
		    	  }
		    	 
			 }
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		 try {
			SC.inFromServer.close();
			SC.setAnswer("Thread beendet");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}	
}

Die Verbindung wird aufgebaut und ich erhalte die Antwort bis 0xff und gebe diese aus.
Doch dann erhalte ich keine daten mehr.

Sende ich im Main mit:
Java:
	public void TCPclient(String data) {
    try {
    	  outToServer.writeBytes(data);
                }
    catch(Exception e) {
       sendOut("status","value",e.getMessage());
    }
 }

wird der Thread beendet weil wohl die Verbindung auch beendet.

Ich vermute das Problem liegt daran, das ich für senden und empfangen den selben Socket nutze und für empfangen immer in einer Schleife laufen lassen muss.

Sieht jemand eine Lösung?

Danke!
 
S

SlaterB

Gast
meine Güte ist das wirr, der Code des dritten Postings hat sich gegenüber den ersten komplett geändert,
geht es weiter um genau einen Client zu einem unbekannten Server?

im Code ist kein wirklicher Fehler zu sehen, mit folgenden kompletten Code funktioniert es lokal:

Java:
public class Test
{
    public static void main(String[] args)
        throws Exception
    {
        new Server().start();
        Thread.sleep(2000);
        Commend c = new Commend();
        c.connect();
        c.TCPclient("Test1");
        Thread.sleep(1000);
        c.TCPclient("Test2");
        Thread.sleep(1000);
        System.out.println("Ende");
        System.exit(0);
    }
}


class Server
    extends Thread
{

    public void run()
    {
        try
        {
            ServerSocket serverSocket = new ServerSocket(4000);
            Socket clientSocket = serverSocket.accept();
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            String inputLine, outputLine;

            while ((inputLine = in.readLine()) != null)
            {
                System.out.println("server empfängt: " + inputLine);
                out.println("Ok\n"); // edit: spät gesehen, das ist ja doppelt \n
                out.flush();
            }
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }

    }

}


class Commend
{
    Socket clientSocket;
    DataOutputStream outToServer;
    BufferedReader inFromServer;
    Listener listen;
    boolean connectet;
    String answer;

    void connect()
    {
        sendOut("connected", "value", "connecting ...");
        try
        {
            String IP = "localhost";
            int Port = 4000;
            clientSocket = null;
            clientSocket = new Socket(IP, Port);
            outToServer = new DataOutputStream(clientSocket.getOutputStream());
            inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
        if (clientSocket.isConnected())
        {
            if (listen == null)
            {
                listen = new Listener(this);
                listen.start();
                connectet = true;
                sendOut("connected", "value", "connected");
            }
        }
    }

    void sendOut(String st1, String st2, String st3)
    {
        System.out.println(st1 + "-" + st2 + "-" + st3);
    }

    public void setAnswer(String answer)
    {
        this.answer = answer;
    }

    public void TCPclient(String data)
    {
        try
        {
            outToServer.writeBytes(data);
            outToServer.writeBytes("\n");
            outToServer.flush();
        }
        catch (Exception e)
        {
            sendOut("status", "value", e.getMessage());
        }
    }
}


class Listener
    extends Thread
{

    public Listener(Commend SC)
    {
        this.SC = SC;
    }

    private Commend SC;
    int answer;

    public void run()
    {
        try
        {
            String EoL = "";
            while (SC.clientSocket.isConnected())
            {
                answer = SC.inFromServer.read();
                if (answer == 255)
                {
                    SC.setAnswer(EoL);
                    EoL = null;
                }
                else if (answer == 10 || answer == 13)
                {
                    EoL += "\\n,";
                }
                else
                {
                    EoL += (char)answer + ",";
                }
                System.out.println("Client empfängt insgesamt: " + EoL);

            }
            SC.inFromServer.close();
            SC.setAnswer("Thread beendet");
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }
    }
}
Ausgabe
Code:
connected-value-connecting ...
connected-value-connected
server empfängt: Test1
Client empfängt insgesamt: O,
Client empfängt insgesamt: O,k,
Client empfängt insgesamt: O,k,\n,
Client empfängt insgesamt: O,k,\n,\n,
Client empfängt insgesamt: O,k,\n,\n,\n,
server empfängt: Test2
Client empfängt insgesamt: O,k,\n,\n,\n,O,
Client empfängt insgesamt: O,k,\n,\n,\n,O,k,
Client empfängt insgesamt: O,k,\n,\n,\n,O,k,\n,
Client empfängt insgesamt: O,k,\n,\n,\n,O,k,\n,\n,
Client empfängt insgesamt: O,k,\n,\n,\n,O,k,\n,\n,\n,
Ende

Kleinigkeiten habe ich bei dir schon geändert, z.B. das Senden von \n, ein Java-Server mit BufferedReader.readLine() reagiert vorher nicht,
flush() ist auch immer hilfreich,
der Empfang mit einzelnen gelesenen Bytes ist bei dir schon komisch, da habe ich die gesendeten \n entwas provisorisch verarbeitet, in diese Richtung müsste Server auch gar nicht Zeilenumbruch senden

--

was genau funktioniert aber eigentlich bei dir nicht?
> Sende ich im Main mit:[..] wird der Thread beendet weil
vor diesem Sende-Aufruf ging alles noch? du bist sicher dass in diesem Moment einfach so Ende ist weil z.B. isConnected() dann false liefert?
 
Zuletzt bearbeitet von einem Moderator:

Fohnbit

Top Contributor
Hallo,

wenn ich den outToServer.close() ausführe, beendet der Thread weil die Conenction wohl auch beendet.

Habs nun erst beim Disconnect eingebaut.

Ja, der Code arbeitet nun korrekt, vielen Dank!!
 

Ähnliche Java Themen

Neue Themen


Oben