Re: Chat client/server print failed
- From: deadpickle <deadpickle@xxxxxxxxx>
- Date: Sun, 27 Jan 2008 09:38:21 -0800 (PST)
THanks alot, those scripts are very simple compared to that confusing
script I was trying to write. What I am trying to do is send the user
name to the server so that it can be added to the client list. I dont
quit get how to do this and could use some help.
The client:
#!/usr/bin/perl
use warnings;
use strict;
use Glib qw(TRUE FALSE);
use Gtk2 -init;
use IO::Socket;
#-------------------Global variables-------------------
my $host = 'Deadpickle-hobo';
my $port = 12345;
my $socket;
my $user;
#-------------------Main Window-------------------
my $window = Gtk2::Window->new;
$window->signal_connect( delete_event => sub { exit } );
$window->set_default_size( 300, 200 );
my $vbox = Gtk2::VBox->new;
$window->add($vbox);
my $scroller = Gtk2::ScrolledWindow->new;
$vbox->add($scroller);
my $textview = Gtk2::TextView->new;
$textview ->set_editable (0);
$textview ->can_focus(0);
my $buffer = $textview->get_buffer;
$buffer->create_mark( 'end', $buffer->get_end_iter, FALSE );
$buffer->signal_connect(insert_text => sub {
$textview->scroll_to_mark( $buffer->get_mark('end'), 0.0,
TRUE, 0, 0.5 );
});
$scroller->add($textview);
my $entry = Gtk2::Entry->new();
$vbox->pack_start( $entry, FALSE, FALSE, 0 );
$vbox->set_focus_child ($entry); # keeps cursor in entry
$window->set_focus_child ($entry); # keeps cursor in entry
# allows for sending each line with an enter keypress
my $send_sig = $entry->signal_connect ('key-press-event' => sub {
my ($widget,$event)= @_;
if( $event->keyval() == 65293){ # a return key press
my $text = $entry->get_text;
if(defined $socket){ print $socket $user.'->'. $text,
"\n";}
$entry->set_text('');
$entry->set_position(0);
}
});
#If you store the ID returned by signal_connect, you can temporarily
#block your signal handler with
# $object->signal_handler_block ($handler_id)
# and unblock it again when you're done with
## $object->signal_handler_unblock ($handler_id).
# we want to block/unblock the enter keypress depending
# on the state of the socket
$entry->signal_handler_block($send_sig); #not connected yet
$entry->set_editable(0);
$window->show_all;
#start the dialog window
dialog();
Gtk2->main;
exit;
#-------------------Login Dialog-------------------
sub dialog{
my $dialog_window = Gtk2::Window->new('toplevel');
$dialog_window->signal_connect(delete_event => sub {Gtk2-
main_quit});
my $dialog_table = Gtk2::Table->new(2, 2, FALSE);
my $dialog_label1 = Gtk2::Label->new('Chat Login:');
my $dialog_label2 = Gtk2::Label->new('User:');
my $chat_user = Gtk2::Entry->new();
$chat_user->set_text('');
my $dialog_button1 = Gtk2::Button->new('Connect');
$dialog_table->attach_defaults($dialog_label1, 0, 1, 0, 1);
$dialog_table->attach_defaults($chat_user, 1, 2, 0, 1);
$dialog_table->attach_defaults($dialog_button1, 1, 2, 1, 2);
#connect to the server
$dialog_button1->signal_connect( clicked => sub {
$user = $chat_user->get_text;
$dialog_window->destroy;
init_connect();
});
$dialog_window->add($dialog_table);
$dialog_window->show_all;
return;
}
#------------------Connect to server---------------------
sub init_connect{
$socket = IO::Socket::INET->new(
PeerAddr => $host,
PeerPort => $port,
Proto => 'tcp',
);
if( ! defined $socket){
my $buffer = $textview->get_buffer;
$buffer->insert( $buffer->get_end_iter, "ERROR: Can't
connect to port $port on $host as $user: $!\n" );
return;
}
# install an io watch for this stream and
# return immediately to the main caller, who will return
# immediately to the event loop. the callback will be
# invoked whenever something interesting happens.
Glib::IO->add_watch( fileno $socket, [qw/in hup err/],
\&watch_callback, $socket );
#turn on entry widget
$entry->set_editable(1);
$entry->grab_focus;
$entry->signal_handler_unblock ($send_sig);
#send the username to the server for handling
print $socket "$user\n";
Gtk2->main_iteration while Gtk2->events_pending;
}
#-------------------Watch for Events-------------------
sub watch_callback {
my ( $fd, $condition, $fh ) = @_;
if ( $condition >= 'in' ) {
# there's data available for reading. we have no
# guarantee that all the data is there, just that
# some is there. however, we know that the child
# will be writing full lines, so we'll assume that
# we have lines and will just use <>.
my $data = scalar <$fh>;
if ( defined $data ) {
# do something useful with the text.
my $buffer = $textview->get_buffer;
$buffer->insert( $buffer->get_end_iter, $data );
}
}
if ( $condition >= 'hup' or $condition >= 'err' ) {
# End Of File, Hang UP, or ERRor. that means
# we're finished.
# stop ability to send
$entry->set_editable(0);
$entry->signal_handler_block ($send_sig);
my $buffer = $textview->get_buffer;
$buffer->insert( $buffer->get_end_iter, "Server connection
lost !!\n" );
#close socket
$fh->close;
$fh = undef;
#allow for new connection
#$button->set_label('Connect');
#$button->set_sensitive(1);
#$button->grab_focus;
#Gtk2->main_iteration while Gtk2->events_pending;
}
if ($fh) {
# the file handle is still open, so return TRUE to
# stay installed and be called again.
# print "still connected\n";
# possibly have a "connection alive" indicator
return TRUE;
}
else {
# we're finished with this job. start another one,
# if there are any, and uninstall ourselves.
return FALSE;
}
}
the server:
#!/usr/bin/perl
use warnings;
use strict;
use IO::Socket;
use threads;
use threads::shared;
my $user;
$|++;
print "$$ Server started\n";; # do a "top -p -H $$" to monitor server
threads
our @clients : shared;
@clients = ();
my $server = new IO::Socket::INET(
Timeout => 7200,
Proto => "tcp",
LocalPort => 12345,
Reuse => 1,
Listen => 3
);
while (1) {
my $client;
do {
$client = $server->accept;
} until ( defined($client) );
$server->recv($user, 300);
my $peerhost = $client->peerhost();
print "accepted a client $client, $peerhost, username = $user \n";
my $fileno = fileno $client;
push (@clients, $fileno);
#spawn a thread here for each client
my $thr = threads->new( \&process_it, $client, $fileno,
$peerhost )->detach();
}
# end of main thread
sub process_it {
my ($lclient,$lfileno,$lpeer) = @_; #local client
if($lclient->connected){
# Here you can do your stuff
# I use have the server talk to the client
# via print $client and while(<$lclient>)
print $lclient "$lpeer->Welcome to server\n";
while(<$lclient>){
# print $lclient "$lpeer->$_\n";
print "clients-> @clients\n";
foreach my $fn (@clients) {
open my $fh, ">&=$fn" or warn $! and die;
print $fh "$_"
}
}
}
#close filehandle before detached thread dies out
close( $lclient);
#remove multi-echo-clients from echo list
@clients = grep {$_ !~ $lfileno} @clients;
}
.
- Follow-Ups:
- Re: Chat client/server print failed
- From: zentara
- Re: Chat client/server print failed
- References:
- Chat client/server print failed
- From: deadpickle
- Re: Chat client/server print failed
- From: zentara
- Re: Chat client/server print failed
- From: zentara
- Re: Chat client/server print failed
- From: deadpickle
- Re: Chat client/server print failed
- From: deadpickle
- Re: Chat client/server print failed
- From: zentara
- Re: Chat client/server print failed
- From: deadpickle
- Re: Chat client/server print failed
- From: zentara
- Chat client/server print failed
- Prev by Date: Re: Regexp to search over several lines in one string
- Next by Date: Re: Regexp to search over several lines in one string
- Previous by thread: Re: Chat client/server print failed
- Next by thread: Re: Chat client/server print failed
- Index(es):
Relevant Pages
|