wavenator has asked for the wisdom of the Perl Monks concerning the following question:

k i've just made server and client of my chat program but i've got a problem

seems like it with the client the client code: -------start of code---------

use threads; use IO::Socket::INET; my $so = new IO::Socket::INET( PeerAddr => '127.0.0.1', PeerPort => 1300, Proto => 'tcp', Reuse => 1, ); die "Socket Error: $!\n" unless $so; my $thread = threads->create("start_thread"); my $thread1 = threads->create("start_thread1"); sub start_thread { while($so->recv($txt,128)){print "server : $txt";} } sub start_thread1 { while(my $msg = <STDIN>){print $so "$msg"; } } $thread->join(); $thread1->join(); --------end of code-----------
sry i dont know how to make my code looks good on the page i think the problem's here :
while($so->recv($txt,128)){print "server : $txt";}
i've already tried with $txt =<$so>

well need ya help btw the problem is not with the server i've tried with telnet and worked perfect

thx for help

Replies are listed 'Best First'.
Re: socket with threads problem
by liverpole (Monsignor) on Oct 10, 2007 at 15:11 UTC
    Hi wavenator,

    You seem to be trying to make two socket connections to the same port on the same host.  What you'll need to do is to move the logic for the socket connections into each of the threads, setup individual server and client socket connections, and use the accept call to accept and handle the client connection.

    Here's a working example, based on your code, with a few modifications:

    use strict; use warnings; + use threads; use IO::Socket::INET; my $port = 1300; my $thread = threads->create("server_thread"); my $thread1 = threads->create("client_thread"); sub server_thread { my %params = ( LocalHost => '127.0.0.1', LocalPort => $port, Proto => 'tcp', Listen => 1, Reuse => 1, ReuseAddr => 1, ); my $so = new IO::Socket::INET(%params); die "Server Socket Error: $!\n" unless $so; print STDERR "[Server Socket Connected]\n"; + my $client = $so->accept(); $client->autoflush(1); + while (1) { my $txt = <$client>; last unless defined($txt); chomp $txt; last if ($txt eq 'quit'); print "server : $txt\n"; } print "[Server finished]\n"; } sub client_thread { sleep 1; # Give the server a head start my %params = ( 'PeerAddr' => '127.0.0.1', 'PeerPort' => $port, 'Proto' => 'tcp', 'ReuseAddr' => 1, ); my $so = new IO::Socket::INET(%params); $so->autoflush(1); die "Client Socket Error: $!\n" unless $so; print STDERR "[Client Socket Connected]\n"; while (my $msg = <STDIN>) { chomp $msg; last if ($msg eq 'quit'); print $so "$msg\n"; } print "[Client finished]\n"; } $thread->join(); $thread1->join();

    The client thread waits for 1 second, to make sure the server thread has time to connect first.  Then the server continues to fetch input from the filehandle returned by the accept call, until the user types "quit", at which point both the server and client threads finish.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      dunno why but ur both codes didnt work and not with my program i've made a simple server that gets a handle from client and send him the msg back and it's just stuck try your own maybe there is another thing maybe a client cant get a m,sg from the server but whats the problem
        maybe the both server and client code will help: client :
        use threads; use IO::Socket; my $so = new IO::Socket::INET( PeerAddr => '127.0.0.1', PeerPort => 1300, Proto => 'tcp', Reuse => 1,); die "Socket Error: $!\n" unless $so; my $thread = threads->create(\&start_thread); my $thread1 = threads->create(\&start_thread1); sub start_thread { while(my $txt=<$so>){print "server : $txt";} } sub start_thread1 { while(my $msg = <STDIN>){ print $so "$msg"; } } $thread->join(); $thread1->join();
        server:
        use threads; use IO::Socket; my $so = new IO::Socket::INET(LocalPort => '1300', Proto => 'tcp', Listen => 10, Reuse => 1,); die "Socket Error: $!\n" unless $so; while (my $client = $so->accept()) { my $thread = threads->create("start_thread"); my $thread1 = threads->create("start_thread1"); print $so "connected\n"; sub start_thread1 { while(my $get=<$client>){print "client : $get";} } sub start_thread { while(my $msg = <STDIN>){ print $so "$msg"; } } $thread->join(); }
Re: socket with threads problem
by zentara (Cardinal) on Oct 10, 2007 at 14:41 UTC
    You need to put code tags around your code. Click on the link "Need Help" to see how to do it. Basically you do <'code'>......put your code here.......<'/code'> Remove the single quotes from around code to make it work.

    As far as your code goes, it sounds like you are looking for a bi-directional client. Here is a forking example. You may be having blocking problems in your code with recv and threads, but since your code is messy, I can't afford the eye strain to figure it out.

    #!/usr/bin/perl -w use strict; use IO::Socket; my ( $host, $port, $kidpid, $handle, $line ); ( $host, $port ) = ('192.168.0.9',1200); my $name = shift || ''; if($name eq ''){print "What's your name?\n"} chomp ($name = <>); # create a tcp connection to the specified host and port $handle = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => $port ) or die "can't connect to port $port on $host: $!"; $handle->autoflush(1); # so output gets there right away print STDERR "[Connected to $host:$port]\n"; # split the program into two processes, identical twins die "can't fork: $!" unless defined( $kidpid = fork() ); # the if{} block runs only in the parent process if ($kidpid) { # copy the socket to standard output while ( defined( $line = <$handle> ) ) { print STDOUT $line; } kill( "TERM", $kidpid ); # send SIGTERM to child } # the else{} block runs only in the child process else { # copy standard input to the socket while ( defined( $line = <STDIN> ) ) { print $handle "$name->$line"; } }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum