tzn jesli dobrze rozumiem, chcesz napisac cos w rodzaju czata ale tak aby bylo widac jak rozmowca wbija kolejne litery a nie przesylanie tekstu calymi liniami, tak?
Normalnie Perl czyta teksty liniami i jest to bardzo rozsadne. Problem polega na tym, ze zdefiniowales 2 funkcje, put($text) i get(). Niestety kazda z funkcji tworzy swoj socket na podanym porcie, wiec pierwsza funkcja zrobi swoje i nadal trzyma socket otwarty a druga ktora zostanie odpalona (get) juz nie dostanie sie do portu - port in use.
Sztuka w zasiegu zmiennych - jesli definiujesz socket w ramach funkcji, jest on dostepny tylko w ramach funkcji. Proponuje abys zaczal pisac z uzyciem modulu strict i wtedy bedziesz musial jasno definiowac zakresy zmiennych - na poczatku to denerwuje ale sie bardzo przydaje przy debugowaniu.
No wiec zrobmy dzialajacy przyklad...
Kod:
#!/usr/bin/perl
use IO::Socket::INET;
use strict;
# wylaczamy buforowanie terminala i uchwytow plikow
# czasami program nic nie wyswietli do czasu zamkniecia strumienia
$|++;
# ta funkcja wysyla przez socket
sub put {
# zmoienne sa lokalne, istnieja tylko wewnatrz procedury
my ($conn, $text) = @_;
print $conn $text;
}
# tutaj czytamy dane z uchwytu polaczenia, jak z pliku
sub get {
my $conn = $_[0]; # my ($conn) = @_; -- inaczej zapisane
# wczytujemy jedna linie - wazne aby to byla osobna operacja,
# bo wewnatrz print'a czasami glupieje
chomp (my $text = <$conn>);
print "----------\n| ", $conn->peerhost, ": $text\n----------\n";
}
# tworzymy sobie socket na ktorym bedziemy sluchac,
# dlugosc kolejki dajemy pro-forma na 5 polaczen, port 23 (telnet) i TCP
# jesli port jest zajety dostaniemy blad i program zakonczy prace
my $socket = IO::Socket::INET->new(Listen => 5,
LocalAddr => 'localhost',
LocalPort => 23,
Proto => 'tcp',
) or die "Nie moge zaczac sluchac na porcie: [email protected]\n";
# akceptujemy dokladnie 1 polaczenie, nie ma petli!
my $conn = $socket->accept();
# grzecznie zapytajmy czego chce nasz gosc
print $conn "Co slychac?\n";
get($conn);
# odczytalismy tekst i wyswietlilismy, to czas odpowiedziec
print "Odpowiedz: ";
my $odp = <STDIN>;
# to mozna tak samo jak wyzej z "co slychac"
put($conn, $odp);
# zamykamy socket w poprawny sposob...
$conn->close();
kod akurat zrobilem i sprawdzilem pod windows i dziala...