Socketproblem

Status
Nicht offen für weitere Antworten.

Bernasconi

Mitglied
Hallo.

Irgendwie kann ich keine Daten mehr übers Netz schicken und ich weiss nicht warum.
Ich will nicht gross labern sondern poste den Code.

die Zeile 114 ist die, die das try beendet und den Catch aufruft.
Warum es nicht funktioniert ist mir nicht klar, da der Socket weiter oben ordnungsgemäss gestartet wird.

Code:
package netzwerk;

import java.net.*;
import java.io.*;
import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

public class Client 
{
	InputStream in;
	OutputStream out;
	JTextField tf;
	String nickname;
	JFrame frame;
	JTextField field;
	JDialog dialog;
	Socket server;
	
	public Client( )
	{
		init();
		openNicknameDialog();
		createGUI();
		setupConnection( "192.168.1.100", 2000 );
	}
	
	private void init()
	{
		in = null;
		out = null;	
		tf = null;
		nickname = "noName";
		frame = null;
		field = null;
		dialog = null;
		server = null;		
	}
	
	private void setupConnection( String ip, int port )
	{
		try
		 {
			 server = new Socket( ip, port ); 
			 in  = server.getInputStream(); 
		     out = server.getOutputStream(); 
		 }
		 catch( Exception e )
		 {
			 tf.setText( "Fehler beim herstellen der Verbindung zum Server." );
		 }  	
	}
	
	private void openNicknameDialog()
	{
		dialog = new JDialog( frame, true );
		dialog.setLayout( new BorderLayout() );
		
		JLabel label = new JLabel( "Nickname:" );
		field = new JTextField();
		JButton but = new JButton( "ok" );
		but.addActionListener( new okListener() );	
		
		dialog.add( BorderLayout.WEST, label );
		dialog.add( BorderLayout.CENTER, field );
		dialog.add( BorderLayout.EAST, but );
		
		dialog.setSize( 300, 80 );
		dialog.setVisible( true );
	}
	
	private void createGUI( )
	{
		frame = new JFrame("Client");
		frame.setLayout( new BorderLayout() );
		tf = new JTextField();
		JButton b = new JButton( "senden" );
		b.setFocusable( false );
		b.addActionListener( new ButtonListener() );
		frame.add( BorderLayout.CENTER, tf );
		frame.add( BorderLayout.EAST, b );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setSize( 300, 80 );
		frame.setVisible( true );  		
	}
	
	class ButtonListener implements ActionListener
	{
		boolean fehler;
		
		public void actionPerformed( ActionEvent e )
		{
			fehler = false;
			sendMessage();
			
			if( !fehler )
				clearEingabe();
		}
		
		private void clearEingabe()
		{
			tf.setText( "" );
		}
		
		private void sendMessage( )
		{
			try
			 {		     
			     String s = nickname + ": " + tf.getText();
			     byte[] bytes = s.getBytes();
			     
			     for( int i=0; i < bytes.length; i++ )
			    	 out.write( bytes[i] );
			     
			     out.flush();
			 }
			 catch( Exception e )
			 {
				 tf.setText( "Die Nachricht konnte nicht gesendet werden." );
				 fehler = true;
			 }  
		}
	}
	
	class okListener implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			nickname = field.getText();
			dialog.setVisible( false );
		}
	}
}
 
G

Gast2

Gast
also ich würde in zeile 45 das hier mal versuchen
Code:
			adresse=InetAddress.getByName(ip);
			socket= new Socket(adresse,port);


und in deinem try catch im catch ein e.printStackTrace() machen dann siehst du mal ne richtige Fehlermeldung.
 

Bernasconi

Mitglied
Gut, das habe ich gerade einmal versucht.

Aber das Problem ist nicht der Aufbau der Verbindung, sondern die Exception wird geworfen, wenn ich etwas senden möchte, also erst bei out.write().

setupConnection funktioniert immer wenn der Server gestartet wurde.

Der Fehler ist folgender:

java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at netzwerk.Client$ButtonListener.sendMessage(Client.java:116)
at netzwerk.Client$ButtonListener.actionPerformed(Client.java:97)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)


An was könnte es liegen?
Es hat ja wie gesagt schonmal funktioniert.
Habe diverse Funktionalitäten dazu geschrieben, aber am senden selbst nichts verändert :-/

neuer Code:
Code:
package netzwerk;

import java.net.*;
import java.io.*;
import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

public class Client 
{
	InputStream in;
	OutputStream out;
	JTextField tf;
	String nickname;
	JFrame frame;
	JTextField field;
	JDialog dialog;
	Socket server;
	
	public Client( )
	{
		init();
		openNicknameDialog();
		createGUI();
		setupConnection( "192.168.1.100", 2000 );
	}
	
	private void init()
	{
		in = null;
		out = null;	
		tf = null;
		nickname = "noName";
		frame = null;
		field = null;
		dialog = null;
		server = null;		
	}
	
	private void setupConnection( String ip, int port )
	{
		try
		 {
			 InetAddress adresse = InetAddress.getByName(ip); 
			 server = new Socket( adresse, port ); 
			 in  = server.getInputStream(); 
		     out = server.getOutputStream(); 
		 }
		 catch( Exception e )
		 {
			 tf.setText( "Fehler beim herstellen der Verbindung zum Server." );
			 e.printStackTrace();
		 }  	
	}
	
	private void openNicknameDialog()
	{
		dialog = new JDialog( frame, true );
		dialog.setLayout( new BorderLayout() );
		
		JLabel label = new JLabel( "Nickname:" );
		field = new JTextField();
		JButton but = new JButton( "ok" );
		but.addActionListener( new okListener() );	
		
		dialog.add( BorderLayout.WEST, label );
		dialog.add( BorderLayout.CENTER, field );
		dialog.add( BorderLayout.EAST, but );
		
		dialog.setSize( 300, 80 );
		dialog.setVisible( true );
	}
	
	private void createGUI( )
	{
		frame = new JFrame("Client");
		frame.setLayout( new BorderLayout() );
		tf = new JTextField();
		JButton b = new JButton( "senden" );
		b.setFocusable( false );
		b.addActionListener( new ButtonListener() );
		frame.add( BorderLayout.CENTER, tf );
		frame.add( BorderLayout.EAST, b );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setSize( 300, 80 );
		frame.setVisible( true );  		
	}
	
	class ButtonListener implements ActionListener
	{
		boolean fehler;
		
		public void actionPerformed( ActionEvent e )
		{
			fehler = false;
			sendMessage();
			
			if( !fehler )
				clearEingabe();
		}
		
		private void clearEingabe()
		{
			tf.setText( "" );
		}
		
		private void sendMessage( )
		{
			try
			 {		     
			     String s = nickname + ": " + tf.getText();
			     byte[] bytes = s.getBytes();
			     
			     for( int i=0; i < bytes.length; i++ )
			    	 out.write( bytes[i] );
			     
			     out.flush();
			 }
			 catch( Exception e )
			 {
				 tf.setText( "Die Nachricht konnte nicht gesendet werden." );
				 e.printStackTrace();
				 fehler = true;
			 }  
		}
	}
	
	class okListener implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			nickname = field.getText();
			dialog.setVisible( false );
		}
	}
}
 

Bernasconi

Mitglied
Zusatzinformation
wenn ich

Code:
out.write( 345 );

in Funktion setupConnection ans Ende setze, funktioniert das auch.


Aber unten in sendMessage funktioniert es dann nicht mehr. Warum? Ich schliesse den Stream ja nirgends.
 
G

Gast2

Gast
benutz doch einen ObjectOutputStream und sende deinen ganzen String rüber....
du musst die ganzen daten nachher auch wieder auf deinem server einlesen...
also ich denk mal du musst bei jedem write musst du auch ein read im server aufrufen....

EDIT
Code:
			out =  new ObjectOutputStream(socket.getOutputStream());
			in= new ObjectInputStream ( socket.getInputStream());


out.writeObject();
 
G

Gast2

Gast
Zusatzinformation
wenn ich

Code:

1


out.write( 345 );




in Funktion setupConnection ans Ende setze, funktioniert das auch.


Aber unten in sendMessage funktioniert es dann nicht mehr. Warum? Ich schliesse den Stream ja nirgends.

also wenn du in sendMessage()
out.write( 345 );
aufrufst funktioniert das nicht????

EDIT: ne andere frage schließt du auch keine Streams auf der Server seite???? weil es sieht so aus als ob du keine verbindung hast....
 

Bernasconi

Mitglied
out.write( 345 );
in sendMessage() funktioniert nicht, nein.

Dein Tipp mit ObjectOutputStream muss ich noch ein bisschen vertiefen. Ich schaue dann, was das genau ist etc. in der API. Aber zuerst muss ich überhaupt mal etwas senden können, bevor ich das ganze weiter anpasse.

Damit du dir selbst ein Bild machen kannst, hier der serverseitige Code:

Code:
package netzwerk;

import java.net.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;

public class Server 
{
	String message;
	JFrame frame;
	JTextArea messagebox;	
	
	public Server( )
	{
		Socket client = null;
		message = "";
		
		createGUI();
		
		try
		{
			ServerSocket serverSocket = new ServerSocket( 2000 );
			
			while( true )
			{
				client = serverSocket.accept();
				handleAnfrage( client );
			}
		}
		catch( Exception e )
		{
			System.out.println( "IOException" );
		}
	}
	
	public void createGUI( )
	{
		frame = new JFrame( "Nachrichtenverlauf" );
		messagebox = new JTextArea();
		frame.setLayout( new BorderLayout());
		JScrollPane scrollpane = new JScrollPane( messagebox );
		frame.add( BorderLayout.CENTER, scrollpane );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setSize( 300, 200 );
		frame.setVisible( true );
	}
	
	private void handleAnfrage( Socket client ) throws IOException
	{
	    InputStream  in  = client.getInputStream(); 
	    OutputStream out = client.getOutputStream(); 

	    System.out.println( "Input/Output Streams bereit" );	    
	    System.out.println( "Eingabe: " );
	    
	    try
	    {
	    	Thread.sleep(1000); 
	    }
	    catch( Exception e )
	    {
	    	
	    }
	    
	    int anzByte = in.available();
	    byte[] input = new byte[anzByte];
	    
	    for( int i=0; i < anzByte; i++ )
	    {
	    	input[i] = (byte)in.read();
	    }
	    
	    String s = new String( input );
	    message = message + s + "\n";
	  
	    messagebox.setText( message );
	    
	    in.close();
	    out.close();
	}
}
 
G

Gast2

Gast
jo hab den fehler
Code:
in.close(); 
out.close();

das schließt dir deine verbindung wenn du ein stream schließt schließt du auch alle damit verbundenen stream

und eine endloschleife im konstruktor ist auch nicht gerade schön....

mach dir ne statische methode waitforClient oder sowas.....

2. Du brauchst noch einen ServerThread der solange läuft wie du senden + empfangen möchtest... und der erst danach deine streams schließt ...

schau mal in die FAQ hats 2 gute Beispiele

Code:
	public static void waitForClient()
	{	

	    	    try
	    {
	    	while(true)
			{
				socket=serverSocket.accept();
				new ServerThread(socket).start();
			}
	    }
	    catch(Exception e)
	    {
	    	e.printStackTrace();
	    }


	}

Code:
public class ServerThread extends Thread
{

	private Socket socket;
	private ObjectOutputStream out;
	private ObjectInputStream sIn;
	
	public ServerThread(Socket s)
	{
		socket=s;
	    try {
			sIn= new ObjectInputStream (socket.getInputStream());
			out= new ObjectOutputStream(socket.getOutputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	   
	}
	
	public void run() 
	{ 
		
		try
		{
			while(true)
			{
				String s=sIn.readObject().toString();				
				if(s.equals("END"))
				{
					break;
				}
			
			}
			
		}
		catch(Exception e)
		{
			e.printStackTrace();
	
		}
		
		try {
			
			out.close();
			sIn.close();
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	} 
}


nicht getestet aber sowas in der art brauchst du....jetzt bleibt deine verbindung solange offen bis du END schickst ....
 

Bernasconi

Mitglied
1.) Gute Idee, danke dir ich habe das versucht umzusetzen.
2.) Wie respk. wo rufe ich jetzt die handleAbfrage() Funktion auf??? Die wird nämlich jetzt nicht mehr aufgerufen.
3.) Wie sende ich jetzt am besten die Daten vom Client zum Server und umgekehrt? Also der Server soll dann den Inhalt der messagebox an den Client schicken. Mit welchen Methoden realisiere ich das am besten?
4.) Warum die waitForClient() Funktion static? Dann habe ich keinen Zugriff auf den serverSocket. Deshalb in meinem Code jetzt nicht mehr static.
5.) Natürlich funktioniert die kommunikation mit dem Client per sendMessage() immer noch nicht. Das würde ich gerne ebenfalls in den Griff bekommen.

Server-Code:
Code:
package netzwerk;

import java.net.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;

public class Server 
{
	String message;
	JFrame frame;
	JTextArea messagebox;	
	ServerSocket serverSocket;
	
	public Server( )
	{	
		init();
		createGUI();
	}
	
	private void init()
	{
		try
		{
			serverSocket = new ServerSocket( 2000 );
		}
		catch( Exception e )
		{
			serverSocket = null;
			e.printStackTrace();
		}	
		
		frame = null;
		messagebox = null;
		message = "";
	}
	
	public void waitForClient()
	{   
		try
	    {
			while(true)
			{
				Socket socket = serverSocket.accept();
	            new ServerThread(socket).start();
	        }
	    }
	    catch(Exception e)
	    {
	        e.printStackTrace();
	    }
	} 
	
	public void createGUI( )
	{
		frame = new JFrame( "Nachrichtenverlauf" );
		messagebox = new JTextArea();
		frame.setLayout( new BorderLayout());
		JScrollPane scrollpane = new JScrollPane( messagebox );
		frame.add( BorderLayout.CENTER, scrollpane );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.setSize( 300, 200 );
		frame.setVisible( true );
	}
	
	private void handleAnfrage( Socket client ) throws IOException
	{
	    InputStream  in  = client.getInputStream(); 
	    OutputStream out = client.getOutputStream(); 

	    System.out.println( "Input/Output Streams bereit" );	    
	    System.out.println( "Eingabe: " );
	    
	    try
	    {
	    	Thread.sleep(1000); 
	    }
	    catch( Exception e )
	    {
	    	
	    }
	    
	    int anzByte = in.available();
	    byte[] input = new byte[anzByte];
	    
	    for( int i=0; i < anzByte; i++ )
	    {
	    	input[i] = (byte)in.read();
	    }
	    
	    String s = new String( input );
	    message = message + s + "\n";
	  
	    messagebox.setText( message );
	    
	    in.close();
	    out.close();
	}
	
	public class ServerThread extends Thread
	{
		private Socket socket;
	    private ObjectOutputStream out;
	    private ObjectInputStream sIn;
	   
	    public ServerThread(Socket s)
	    {
	    	socket = s;
	    	
	    	try 
	    	{
	    		sIn= new ObjectInputStream( socket.getInputStream() );
	    		out= new ObjectOutputStream( socket.getOutputStream() );
	    	} 
	    	catch (IOException e) 
	    	{
	    		e.printStackTrace();
	    	}	      
	    }
	    
	    public void run()
	    {
	    	try
	    	{
	    		while(true)
	    		{
	    			String s = sIn.readObject().toString();            
	    			
	    			if(s.equals("END"))
	    			{
	    				break;
	    			}
	         
	    		}     
	    	}
	    	catch(Exception e)
	    	{
	    		e.printStackTrace();
	    	}
	    	    
	    	try 
	    	{
	    		out.close();
	    		sIn.close();
	    		socket.close();
	    	} 
	    	catch (IOException e) 
	    	{
	    		e.printStackTrace();
	    	}
	   }
	} 
}
 
G

Gast2

Gast
du brauchst die handel Methode nicht mehr... Des weiteren solltest du deine GUI und deine fachliche Klasse trennen und der ServerThread sollte keine innere Klasse sein sondern eine eigene....
in dieser ServerThread musst du jetzt deine Nachrichtenstrukur aufbauen...
wie z.B. der Client schickt an den Server Nachricht1 dann weiß der Server er soll dem client etwas senden...
2 .Wann willst du das TextFeld auslesen und senden???Eventhandling?????
3. sobald der server sendet muss der client das wissen.....Versteh nicht wie du das vorhattest, da eigentlich der client ne anfrage macht und danach der server diese bearbeitet und gegebenfalls etwas zurück sendet...


z.B.




Code:
public class ServerThread extends Thread 
   { 
       private Socket socket; 
       private ObjectOutputStream out; 
       private ObjectInputStream sIn; 
       private String area;                 --> welches du mit einer setMethode irgendwann im Server mal setzen musst
       
       public ServerThread(Socket s) 
       { 
          socket = s; 
           
          try 
          { 
             sIn= new ObjectInputStream( socket.getInputStream() ); 
             out= new ObjectOutputStream( socket.getOutputStream() ); 
          } 
          catch (IOException e) 
          { 
             e.printStackTrace(); 
          }         
       } 
       
       public void run() 
       { 
          try 
          { 
             while(true) 
             { 
                String s = sIn.readObject().toString();    -> hier wir gelesen    
                 
                 if(s.equals("nachricht1")) 
                { 
                         
                   out.writeObject(area);-->hier wird gesendet
                   out.writeObject("OK");  
                } 

                if(s.equals("END")) 
                { 
                   break; 
                } 
             
             }      
          } 
          catch(Exception e) 
          { 
             e.printStackTrace(); 
          } 
              
          try 
          { 
             out.close(); 
             sIn.close(); 
             socket.close(); 
          } 
          catch (IOException e) 
          { 
             e.printStackTrace(); 
          } 
      } 
   }


Auf der client Seite vielleicht so etwas das ist nur ein beispiel...

Code:
	public static Object senden(String nachricht) throws Exception
	{

		out.writeObject(nachricht);  -->hier wird gesendet
		out.flush();
		return empfangen();	
	}


public static Object empfangen() 
{
		Object o =null;
		Object retour=null;
	

    	while(true)
    	{
    		try
    		{
    		o =sIn.readObject();
    		} catch (Exception e) {
	    	 e.printStackTrace();
    		} 

    		if(o==null)break;
    		if(o.toString().equals("Fehler"))
    		{
    			o =sIn.readObject();
    			JOptionPane.showErrorMessage("Fehler:"+" \n"+o.toString());
    			break;
    		}

    		if(o instanceof Object[])
    		{
    			retour= o;
    		}
    		
    		if(o instanceof String)
    		{
    			retour= o;
    		}
    		
    		if(o.equals("OK"))
    		{
    			break;
    		}
    		
    	}
    	return retour;

}
 

Bernasconi

Mitglied
out.writeObject(nachricht); //-->hier wird gesendet

das scheint eine undefinierte Methode vom Typ OutputStream zu sein.
Ausserdem komme ich überhaupt nicht nach, wie das jetzt mit dem senden / empfangen funktionieren soll.

Ich bitte dich mir ein möglichst einfaches Beispiel zu zeigen. Vielleicht mit einer minimalsten Client und Server seite. Wenns nur etwas ganz kleines ist, ist mir schon geholfen.

Java ist für mich eigentlich recht klar, was GUI anbelangt und die Basics. Aber ich verstehe halt genau das mit dem senden/empfangen, der Sockets und den Streams noch nicht so. Ich bitte um ein einfaches, einleuchtendes Beispiel.

Dann werde ich hoffentlich und vermutlich das von dir gepostet verstehen und auch anwenden können.
 
G

Gast2

Gast
hier ist ein kleines beispiel!!!
Server starten ,Client starten was in das textfeld hineinschreiben server gibt das in der konsole aus und schickt eine bestätigung zurück....

clientsever.jar
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben