Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]4454[/thread]

Socket-Server, ich verstehe es nicht ganz: Perl-Server+C#-Client-> Bi-Direkt.-Verbi

Leser: 1


<< |< 1 2 >| >> 16 Einträge, 2 Seiten
Gast Gast
 2007-02-20 14:14
#37459 #37459
Hi,

es geht um einen Socket-Server in Perl. Er soll Verbindungen mit einem C#-Programm annehmen können. Das C#-Programm soll dem perl-Server Daten schicken, dieser wiederum antworten.

Aber ich bekomme keine befriedigenden Ergebnisse, das liegt sicher daran, dass ich ein absoluter Perl-Anfänger bin. In die FAQ habe ich schon geschaut und auch ein toturial durchgelesen, ich blicke es aber nicht ganz :-(

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/perl

use IO::Socket;

my $client = 0;
my $server_socket = new IO::Socket::INET ( localPort => 13, Listen => $SOMAXCONN, Proto => 'tcp', Reuse => 1) || die "blabla";

print "\nWartend..\n";

&read();

$server_socket->close();

sub read()
{
$client = $server_socket->accept();
print <$client>;
}


Es funktioniert (schon mal gut), d.h. ich kann mit dem C#-Client-Programm einen text rüberschicken, aber der Text wird nur angezeigt, sobald der Client die verbindung trennt.

Dabei müsste der text doch sofort ausgegeben werden, nachdem sich der Client verbunden hat, also gleich nach accept()??!?

Wo liegt mein Denkfehler?

Für Tipps wäre ich echt dankbar, ist übrigens mein erstes Posting hier.
kristian
 2007-02-20 15:31
#37460 #37460
User since
2005-04-14
684 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo

Warum machst du dir das Leben schwer?
Lies perldoc perlipc, da findest du dann auch diverse funktionierende Beispiele für Server.

Gruss
Kristian
no1gizmo
 2007-02-20 16:19
#37461 #37461
User since
2007-02-20
21 Artikel
BenutzerIn
[Homepage] [default_avatar]
Diese Beispiele dieser Tutorials bringen mich nur durcheinander, da verstehe ich nicht, was an jener stelle eindeutig passiert. Ich will den hintergrund verstehen und nicht einfach nur abschreiben.

Deshalb suche ich Hilfe, vielleicht kann mir ja jemand speziell bei diesem Problem helfen. Es ist ja nichtmal ein technisches Problem, sondern mein Verständnisproblem.

Trotzdem danke für den Verweis auf diese Dokus.
esskar
 2007-02-20 16:37
#37462 #37462
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
<$client> versucht solange vom socket zu lesen, bis ein ein \n empfangen wird oder die leitung unterbrochen wird (quasi TextReader.ReadLine in C#).
wenn dein protokol nicht zeilenweise aufgebaut ist, ist es geschickter, die länge der nachricht in die ersten 4 bytes zu packen und dann mit $socket->read zuerst die ersten 4 bytes der nachricht und dann die restlichen daten zu lesen. sonst kommst du immer in diesen blocked state...
außerdem solltest du mit IO::Select testen, ob daten auf dem socket vorhanden sind, bevor du anfängst zu lesen.
HTH\n\n

<!--EDIT|esskar|1171982337-->
no1gizmo
 2007-02-20 16:56
#37463 #37463
User since
2007-02-20
21 Artikel
BenutzerIn
[Homepage] [default_avatar]
[quote=esskar,20.02.2007, 15:37]<$client> versucht solange vom socket zu lesen, bis ein ein \n empfangen wird oder die leitung unterbrochen wird (quasi TextReader.ReadLine in C#).[/quote]

Na das ist doch mal ne Erklärung! Kurz, bündig, verständlich (und mit Vergleich aus "meiner" Welt).

Quote
wenn dein protokol nicht zeilenweise aufgebaut ist, ist es geschickter, die länge der nachricht in die ersten 4 bytes zu packen und dann mit $socket->read zuerst die ersten 4 bytes der nachricht und dann die restlichen daten zu lesen. sonst kommst du immer in diesen blocked state...


->read(...) habe ich schonmal irgendwo gesehen, dann muss ich diese methode (bzw. wie sie genau funktioniert/Parameter) suchen. Was du meinst ist mir aber glaube ich klar. Danke.


Quote
außerdem solltest du mit IO::Select testen, ob daten auf dem socket vorhanden sind, bevor du anfängst zu lesen.


Ahha.... Select sagt mir soweit nicht mehr, als dass ich es schonmal in nem Tutorial gesehen habe, aber nagut, muss ich noch nachforschen.

Insgesamt bin ich wohl MSDN verwöhnt, bei Perl ist das schon Fuselkram, zumal alle Socket-musterlösung im Netz anders funktionieren (zu sein scheinen!?).\n\n

<!--EDIT|no1gizmo|1171983424-->
kristian
 2007-02-20 17:45
#37464 #37464
User since
2005-04-14
684 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo

[quote=no1gizmo,20.02.2007, 15:19]Diese Beispiele dieser Tutorials bringen mich nur durcheinander, da verstehe ich nicht, was an jener stelle eindeutig passiert. Ich will den hintergrund verstehen und nicht einfach nur abschreiben.[/quote]

Sehr löblich ;-)

[quote=no1gizmo,20.02.2007, 15:19]
Deshalb suche ich Hilfe, vielleicht kann mir ja jemand speziell bei diesem Problem helfen. Es ist ja nichtmal ein technisches Problem, sondern mein Verständnisproblem.[/quote]

Für mich war und ist dieses spezielle Problem nicht wirklich erkennbar.
Der von dir gepostete Code funktioniert auf meinen Rechnern (Linux) nicht.

In "perldoc perlipc" findet sich die Definition eines Internet-Zeilenendes:
The Internet line terminator is "\015\012". Under ASCII variants of Unix, that could usually be written as "\r\n", but under other systems, "\r\n" might at times be "\015\015\012", "\012\012\015", or something completely different. The standards specify writing "\015\012" to be conformant (be strict in what you provide), but they also recommend accepting a lone "\012" on input (but be lenient in what you require).

Man erfährt auch was SOMAXCONN ist.
The low-level Socket module has a special symbol for the system maximum, which ist SOMAXCONN.
$SOMAXCONN - in deinem Code - ist nicht definiert.

Es hätte auch an einem fehlenden $client->autoflush(1); liegen können, was aber laut Zitat "perldoc IO::Socket"
As of VERSION 1.18 all IO::Socket objects have autoflush turned on by default. This was not the case with earlier releases.
eher unwahrscheinlich ist.


[quote=no1gizmo,20.02.2007, 15:19]
Trotzdem danke für den Verweis auf diese Dokus.[/quote]

Ähem, perldoc ist ein Programm um DIE Perl-Dokumentation zu lesen.
Du solltest das mal gesehen haben.

Gruss
Kristian
esskar
 2007-02-20 17:56
#37465 #37465
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
du kannst die dokus z.b. auch auf search.cpan.org nachschlagen! (find msdn aber auch schicker ;)

IO::Select macht im grunde das selbe wie c# System.Net.Sockets.Socket.Select
no1gizmo
 2007-02-21 11:43
#37466 #37466
User since
2007-02-20
21 Artikel
BenutzerIn
[Homepage] [default_avatar]
Gut um das Select kümmere ich mich noch (in C# hab ichs auch noch nie verwendet).

Das hat wohl aber nichts mit meinem Problem zu tun.

Also nochmal, mein Problem ist, dass die ganze Sache blockiert, also, wenn ich dem Server einen text zum Ausgeben schicke, dann wird dieser erst ausgegeben, wenn die Verbindung unterbrochen wurde (der Client schließt die Verbindung).

Ich habe mal was anderes aussprobiert, es passiert das selbe, wie im opbigen Code.
Code: (dl )
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
#!/usr/bin/perl

use IO::Socket;

socket(SOCKET,PF_INET,SOCK_STREAM, getprotobyname('tcp')) || die "blabla";

$sockaddr = sockaddr_in(13, INADDR_ANY);

bind (SOCKET, $sockaddr) || die "bind tuts nich";

listen(SOCKET, SOMAXCONN) || die "listen tuts nicht";

print "/nWartend\n";

&read();

close(SOCKET);

sub read()
{
accept(CONNECT,SOCKET);

while(defined($line= <CONNECT>))
{
print $line;
}

close(CONNECT);
}


tja und wie das mit ->read() funktioniert weiß ich nicht :-( Ich finde in den tutorials immer nur die Möglichkeit, wie das Handle (direkt oder wie hier indirekt) der print-funktion übergeben wird.
no1gizmo
 2007-02-21 11:57
#37467 #37467
User since
2007-02-20
21 Artikel
BenutzerIn
[Homepage] [default_avatar]
Naja, doch noch eine andere Möglichkeit, die aber auch genau das gleiche Ergebnis liefert!

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/perl

use IO::Socket;

my $client = 0;
my $server_socket = new IO::Socket::INET ( localPort => 13, Listen => $SOMAXCONN, Proto => 'tcp', Reuse => 1) || die "blabla";

print "\nWartend..\n";

&read();

$server_socket->close();

sub read()
{
$client = $server_socket->accept();
my $byte;
while (sysread($client, $byte, 1) == 1) {
print STDOUT $byte;
}
}


Ausgabe erfolgt erwartungsgemäß, nur eben erst dann, wenn die verbindung geschlossen wurde! ich brauche aber eine sofortige Ausgabe (wie ein Chat oder so).\n\n

<!--EDIT|no1gizmo|1172051951-->
esskar
 2007-02-21 12:09
#37468 #37468
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
was schickst du denn nun mit deinem client?
bzw. kannst du mal den code von deinem client posten?
<< |< 1 2 >| >> 16 Einträge, 2 Seiten



View all threads created 2007-02-20 14:14.