Hallo Andre, "Andre Heine" wrote:
ich schreibe gerade einen kl. Serveranwendung, der Server ist in perl, der Client in Java.
Das klappt ganz gut!
Nur womit wird der Socket Stream abgeschlossen?
der ganze Strom wird durch das Schließen der (TCP-)Verbindung abgeschlossen, ohne daß dafür ein Steuerzeichen in den Strom selbst eingefügt wird. Aber das ist anscheinend nicht das, was Du meinst.
Der Client sendet einen String "hallo", in perl will diesen String auswerten.
if ( $string eq 'hallo') print "$string";
Ich habe schon versucht, mit chomp das "\n" zu entfernen, reicht aber scheinbar nicht.
Ich nehme dann mal an, daß Du in Java eine der Funktionen zum Schreiben einer ganzen Zeile mit automatischem Anhängen eines Zeilenumbruchs benutzt hast. Es könnte sein, daß dabei die Zeilen nicht nur mit einem Linefeed, sondern mit der Kombination Carriage-Return + Linefeed ("\r\n") abgeschlossen werden. Sie mal in der Dokumentation der entsprechenden Java-Klassen nach, da sollte was dazu drin stehen.
Also mache ich noch ein "chop" hinterher, jetzt funktioniert das ganze. Aber was hängt denn da nun eigentlich für ein Steuerzeichen hinter?
Falls obige Vermutung zutrifft, läßt das chomp natürlich noch ein "\r" am Ende des Strings übrig. Mit dem zusätzlichen chop wird dieses entfernt -- aber das Funktioniert mehr "zufällig" (eben weil's das letzte Zeichen ist), ist aber keine besonders saubere und robuste Lösung.
Ist das Sprachübergreifend gleich?
Nein, nicht unbedingt. Sprachen (bzw. zugehörige Bibliotheken) stellen mitunter Hilfsmittel zum Lesen oder Schreiben von Textzeilen zur Verfügung. Die genauen Eigenschaften dieser Hilfmittel sollte man jeweils in der Dokumentation nachlesen, denn da kann es durchaus feine Unterschiede geben -- nicht nur zwischen verschiedenen Sprachen, sondern vor allem auch bei der gleichen Sprache auf unterschiedlichen Plattformen. Beispiel: In Unix-artigen Systemen ist der übliche Zeilenumbruch in Textdateien ein einfaches "\n", unter MS-DOS bzw. Windows dagegen die Kombination "\r\n". Dementsprechend verhalten sich die C-Funktionen fread(), fwrite() etc. je nach Plattform unterschiedlich, wenn der Stream beim fopen() als Text- und nicht als Binärdatei geöffnet wurde: Unter Unix würde etwa beim Schreiben ein "\n" unverändert geschrieben, aber unter MS-DOS würde ein C-Stream "on the fly" ein "\r\n" daraus machen. Ich denke, in anderen Sprachen (z.B. Java) werden solche Mechanismen auch verfügbar sein. Der Programmierer wird so dabei unterstützt, die in der jeweiligen Umgebung üblichen Konventionen einzuhalten. Wenn nicht alle beteiligten Programme die gleichen Konventionen einhalten, gibt's natürlich ein Problem. Sowas passiert besonders gerne, wenn ein Datenaustausch (z.B. über's Netz) zwischen verschiedenen Plattformen stattfindet. Gängige Problemquellen sind z.B. unterschiedliche Byte-Order, verschiedene Zeichensätze oder eben unterschiedliche Repräsentation von Zeilenenden. Die Lösung besteht darin, für die Übertragung ein Protokoll zu definieren, daß die genaue Darstellung für den Datenaustausch festlegt. Man kann natürlich auch bewußt bestimmte Spielräume lassen und fordern, daß der Empfänger mit allen Varianten klarkommen muß. In Deinem Fall könntest Du z.B. sagen, daß der Empfänger verschiedene Darstellungen des Zeilenendes handhaben können muß. Für die Realisierung in perl gibt `perldoc -f chomp` Hinweise, wie sich daß Verhalten von chomp beeinflussen läßt. Du könntest auch einem String in der Variable $line mit $line =~ s/[\r\n]+$//; von allen Carriage-Returns und Linefeeds am Ende befreien, egal, in welcher Anzahl und Reihenfolge die da stehen. Soviel ist wohl meist nicht nötig, und $line =~ s/\r?\n$//; reicht, um am Zeilenende ein Linefeed und -- falls vorhanden -- ein vorangestelltes Carriage-Return zu entfernen. Die etwas sauberere Variante wäre es, für Deine Kommunikation genau festzulegen, wie ein ein Zeilenumbruch auszusehen hat (z.B. genau ein Linefeed), und dann in allen beteiligten Programmen sicherzustellen, daß (unabhängig von der jeweiligen Plattform) genau diese Darstellung auch verwendet wird. Übrigens verwenden etliche textbasierte Protokolle (z.B. auch HTTP, SMTP und NNTP) tatsächlich die Kombination von Carriage-Return und Linefeed als Zeilentrenner. Eilert -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Eilert Brinkmann -- Universitaet Bremen -- FB 3, Informatik eilert@informatik.uni-bremen.de - eilert@tzi.org http://www.informatik.uni-bremen.de/~eilert/