ubuntuusers.de

[Vala] Server/Client Kommunikation

Status: Gelöst | Ubuntu-Version: Ubuntu 12.04 (Precise Pangolin)
Antworten |

sacridex

Anmeldungsdatum:
9. Dezember 2009

Beiträge: 91

Hallo,

ich habe ein einfaches Server- und Clientprogramm geschrieben, nur gibt es da ein kleines Problem. Hier erstmal der Code(größtenteils aus den Vala Tutorials übernommen):

Server:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void process_request (InputStream input, OutputStream output) throws Error
{
    var data_in = new DataInputStream (input);
    string line;
   
	while ((line = data_in.read_line (null)) != null)
	{
	    stdout.printf ("%s\n", line);
	}
    
    string content = "Hello!";
    stdout.printf ("Geschickt?: %lu\n", output.write (content.data));
    output.flush ();
}

int main ()
{
    try
    {
        var service = new SocketService ();
        service.add_inet_port (1337, null);
        service.start ();
        while (true)
        {
            var conn = service.accept (null);
            process_request (conn.input_stream, conn.output_stream);
        }
    }
    catch (Error e)
    {
        stderr.printf ("%s\n", e.message);
    }
    return 0;
}

Client:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Client : Object
{
	public Client ()
	{
		var add = new InetAddress.from_string ("127.0.0.1");
		
		try
		{
			var sock = new SocketClient ();
			var conn = sock.connect (new InetSocketAddress (add, 1337));
			conn.output_stream.write ("test\n".data);
			
			var response = new DataInputStream (conn.input_stream);
			var line = response.read_line (null);
			stdout.printf ("erhaltene Nachricht: %s\n", line);
		}
		catch (Error e)
		{
			stdout.printf ("error: " + e.message + "\n");
		}
		
		
	}
	
	public static int main ()
	{
		new Client ();
		
		return 0;
	}
}

Es klappt soweit, dass der Server den empfangenen Text ausgibt, nur wird die Antwort nicht zurückgeschickt. Erst wenn ich den Client beende, wird die Nachricht versandt, was natürlich zu spät ist. ☹ Hat jemand ne Idee? Danke

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Klingt nach ein IO-Caching... vermutlich musst Du irgend wo explizit angeben, dass ein Buffer geleert werden soll.

sacridex

(Themenstarter)

Anmeldungsdatum:
9. Dezember 2009

Beiträge: 91

Beim Server hatte ich den Outputstream schon geflushed, habe das jetzt beim Client auch hinzugefügt. Hat sich aber leider nichts geändert. Auch wenn ich die Outputstreams nach Benutzung schließe, ändert sich nichts.

Muss sich evtl. etwas am InputStream machen?

radoe2

Anmeldungsdatum:
30. November 2006

Beiträge: 243

Ohne jetzt Vala/gio im Detail zu kennen: der read_line Aufruf wird nur dann null zurückliefern und damit deine while-Schleife im Server beenden, wenn die Netzwerkverbindung geschlossen wurde. Nimm das zurücksenden an den Client in die while-Schleife mit auf, dann sollte das gehen.

sacridex

(Themenstarter)

Anmeldungsdatum:
9. Dezember 2009

Beiträge: 91

Danke, das hilft schonmal ein bisschen weiter.

Habe jetzt die while Schleife komplett entfernt. Dann wird die Nachricht vom Server auch direkt versandt(vorher ist er ewig in der while Schleife gehangen und hat auf eine zweite Nachricht gewartet). Jedoch kommt sie beim Client nicht an. Wenn ich den Server beende, dann kommt sie an...

Der Client hängt definitiv am read_line... wird damit erst fertig, wenn der Server geschlossen wird. Habe den Stream aber geflushed, was habe ich vergessen? (auch schon mit close zusätzlich probiert)

Scheint ja irgendwie ein ähnliches Problem zu sein.

sacridex

(Themenstarter)

Anmeldungsdatum:
9. Dezember 2009

Beiträge: 91

Habe jetzt rausgefunden, wie ich zumindest einmal etwas zum Server schicken kann, und dann eine Antwort zurück an den Client schicken kann, hier der Code:

Server:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void process_request (InputStream input, OutputStream output) throws Error
{
    var data_in = new DataInputStream (input);
    var line = data_in.read_line (null);
	stdout.printf ("Erhaltene Nachricht: %s\n", line);
    
    string content = "Hallo!";
    stdout.printf ("Gesendete Zeichen: %lu\n", output.write (content.data));
    output.flush ();
}

int main ()
{
    try
    {
        var service = new SocketService ();
        service.add_inet_port (1337, null);
        service.start ();
        while (true)
        {
            var conn = service.accept (null);
            process_request (conn.input_stream, conn.output_stream);
            /*
             *	Erst wenn ich die Verbindung schließe, kommt die Nachricht vom Server an den Client an...
             */
            conn.close ();
        }
    }
    catch (Error e)
    {
        stderr.printf ("%s\n", e.message);
    }
    return 0;
}

Client:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Client : Object
{
	public Client ()
	{
		var add = new InetAddress.from_string ("127.0.0.1");
		
		try
		{
			var sock = new SocketClient ();
			var conn = sock.connect (new InetSocketAddress (add, 1337));
			conn.output_stream.write ("test\n".data);

			var response = new DataInputStream (conn.input_stream);
			var line = response.read_line (null);
			stdout.printf ("Erhaltene Nachricht: %s\n", line);
		}
		catch (Error e)
		{
			stdout.printf ("error: " + e.message + "\n");
		}
		
		
	}
	
	public static int main ()
	{
		new Client ();
		
		return 0;
	}
}

Habe die entscheidende Stelle beim Server kommentiert. Ich muss die Verbindung schließen, damit die Nachricht beim Client ankommt! Wieso ist das so? Wenn ich vom Client an den Server schicke, klappt es ja auch.

Und wie kann ich dann eine längere Kommunikation zwischen einem Client und Server bewerkstelligen? z.B. Login und dann Daten synchronisieren.

sacridex

(Themenstarter)

Anmeldungsdatum:
9. Dezember 2009

Beiträge: 91

Manchmal sieht man einfach den Wald vor lauter Bäumen nicht! Ich habe das \n vergessen... 😉

Antworten |