Client Program not Receiving Message from Server

Client Program not Receiving Message from Server

am 18.01.2008 18:27:26 von deadpickle

My chat client/server program does not seem to be receiving messages.
It utilizes a Glib::Timeout to loop a sub named wait_for_msg that
listen for the server to send the message so that it can be received
and displayed in the Textview widget. The program connects to the
server fine, logs in great. When the user types in the entry box and
hits send, the program sends the entered message to the server and it
is then sent to all clients including the author of the message. The
problem is that the client is not receiving the message from the
server; I suspect it is the timer. I tried printing text in the loop
to see if it was still running but it only printed once which could
mean that it has stopped working. Any ideas on how to remedy this
problem?

#!/usr/bin/perl
# Flow of the Program:
# *Send message to the server - send_msg_all
# *Connect to the server - sub connect_server
# -unblock the server - nonblock
# -Login to the server - send_login
# -Timer started to wait for messages - wait_for_msg
# >Handler - handle
# $Process the incoming messages - process_incoming
# @Recieve messages and display in textview - rcv_msg_all

use warnings;
use strict;
use Gtk2 -init;
use Glib qw/TRUE FALSE/;
use IO::Socket::INET;
use Tie::RefHash;
use IO::Select;

#global variables
my $buffer;
my $host = "Deadpickle-hobo";
my $port = 6666;
my $conn_stat = 'idle';
my %inbuffer = ();
my %outbuffer = ();
my %ready = ();
my $select;
my $conn;
my $user;

#the main chat widget
my $main_window = Gtk2::Window->new("toplevel");
$main_window->signal_connect(delete_event => sub {Gtk2->main_quit;});
$main_window->set_default_size(250, 200);

my $table = Gtk2::Table->new(4, 2, FALSE);

$buffer = Gtk2::TextBuffer->new;
my $button = Gtk2::Button->new("Send");
my $entry = Gtk2::Entry->new();

my $label = Gtk2::Label->new("Chat Client Test");

my $textview = Gtk2::TextView->new_with_buffer($buffer);
$textview->set_cursor_visible (FALSE);
my $swindow = Gtk2::ScrolledWindow->new( undef, undef);
$swindow->set_policy( 'automatic', 'automatic');
$swindow->set_shadow_type( 'etched-out');

$swindow->add( $textview);

$table->attach_defaults($label, 0, 1, 0, 1);
$table->attach_defaults($swindow, 0, 2, 1, 3);
$table->attach_defaults($entry, 0, 1, 3, 4);
$table->attach_defaults($button, 1, 2, 3, 4);
$main_window->add($table);

$main_window->show_all();

$button->signal_connect("clicked" => sub { send_msg_all($entry-
>get_text); $entry->set_text('');} );

#run the login dialog
dialog($buffer);

Gtk2->main;

#-------------------Login Dialog-------------------
sub dialog{
my $buffer = shift;

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 $dialog_label3 = Gtk2::Label->new('Host:');
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);

$dialog_button1->signal_connect("clicked" => sub {$user = $chat_user-
>get_text; $dialog_window->destroy; $buffer->insert(($buffer-
>get_end_iter), "Username: $user...\n"); connect_server()});

$dialog_window->add($dialog_table);

$dialog_window->show_all;

return 1;
}
#------------------Connect to server---------------------
#establishes connection to the server
sub connect_server{
if ($conn_stat ne 'connected') {
$buffer->insert(($buffer->get_end_iter), "Connecting to Server
$host:$port...\n");

$conn = IO::Socket::INET->new(PeerAddr => $host, PeerPort =>
$port, Proto => 'tcp') or popup_err(1);

if ($conn) {
%inbuffer = ();
%outbuffer = ();
%ready = ();
tie %ready, 'Tie::RefHash';
nonblock($conn);
$select = IO::Select->new($conn);
$conn_stat = 'connected';
$buffer->insert(($buffer->get_end_iter), "Connected!\n");

#send login to server
send_login();

#start the timer that monitors incoming messages
my $timer_waiting = Glib::Timeout->add(100, \&wait_for_msg);
}
}
}
#-------------------Error popup-------------------
# pops up an error message
sub popup_err{
my ($error_code) = @_;
my $error;

if ($error_code == 1) {$error = "Cannot create Socket!"}
elsif ($error_code == 2) {$error = "Username to Short!"}
elsif ($error_code == 3) {$error = "No connection Established!"}
elsif ($error_code == 4) {$error = "Already Logged on with This User
Name!"}
elsif ($error_code == 5) {$error = "Not Connected!"}
else {$error = "Unkown Error!"}

$buffer->insert(($buffer->get_end_iter), "$error\n");

my $error_dialog = Gtk2::MessageDialog->new($main_window, 'destroy-
with-parent', 'error', 'ok', "$error");

$error_dialog->run;
$error_dialog->destroy;
}
#-------------------blocking-------------------
# nonblock($socket) puts socket into nonblocking mode
sub nonblock { my $socket = shift; $socket->blocking(0);}
#-------------------Message Waiting-------------------
# Wait for incoming messages from the server relayed from clients
sub wait_for_msg {

if ($conn_stat eq 'connected') {
my ($list_size, $msg);
my $server;
my $rv;
my $data;

print "waiting..\n";

# check for new information on the connections we have
# anything to read or accept?
foreach $server ($select->can_read(1)) {
# read data
$data = '';
$rv = $server->recv($data, 'POSIX::BUFSIZ', 0);
$inbuffer{$server} .= $data;

# test whether the data in the buffer or the data we
# just read means there is a complete request waiting
# to be fulfilled. If there is, set $ready{$client}
# to the requests waiting to be fulfilled.
while ($inbuffer{$server} =~ s/(.*\n)//) {

push( @{$ready{$server}}, $1 );
}
}

# Any complete requests to process?
foreach $server (keys %ready) {

handle($server);
}
}
}
#-------------------Handler-------------------
# handle($socket) deals with all pending requests for $client
sub handle {
# requests are in $ready{$server}
# send output to $outbuffer{$server}
my $server = shift;
my $request;

print "HANDLER WORKING\n";

foreach $request (@{$ready{$server}}) {
# $request is the text of the request
# put text of reply into $outbuffer{$client}
chomp $request;
process_incoming($server, $request);
}
delete $ready{$server};
}
#-------------------Process Incoming-------------------
sub process_incoming {
my ($server, $msg) = @_;
my @logged_users;
my @rcvd_msg = split(/::/, $msg);

if ($rcvd_msg[1] eq "1") {
if($rcvd_msg[2] eq "03") {
print "Successfully Logged in!\n";
} elsif ($rcvd_msg[2] eq "12") {
popup_err(4);
} else {
# Create pop-up for error!
print "Error Logging in ", $msg, "\n";
popup_err(5);
}
}
elsif ($rcvd_msg[1] eq "7") {
# receive global message
print "$msg\n";
rcv_msg_all($rcvd_msg[3], $rcvd_msg[4
} else {
print "Unrecognized response: $msg\n";
exit(0);
}
}
#-------------------Send message to all-------------------
sub send_msg_all {
my ($msg) = @_;

print "$conn\n";

if(defined $conn) {
# Send a the Message to server
print "Sending\n";
print $conn "7\:\:$user\:\:$msg\n";
} else {
popup_err(3);
}
}
#-------------------Send login-------------------
#logs the user name on the server
sub send_login {
# my ($u) = @_;

if(defined $conn) {
if(length($user) > 0) {
#send login to server
print $conn "1\:\:$user\n";
# update_info();
} else {
popup_err(2);
}
} else {
popup_err(3);
}
}
#-------------------Display All Message-------------------
sub rcv_msg_all {
my ($from, $msg) = @_;

print "Received Global message:\n";
if(defined $conn) {
print "Already Connected: Proceeding with message!\n";
$buffer->insert(($buffer->get_end_iter), "$from: $msg\n");
} else {
print "No connection established!\n";
popup_err(3);
}
}

Re: Client Program not Receiving Message from Server

am 19.01.2008 01:42:07 von deadpickle

On Jan 18, 11:27 am, deadpickle wrote:
> My chat client/server program does not seem to be receiving messages.
> It utilizes a Glib::Timeout to loop a sub named wait_for_msg that
> listen for the server to send the message so that it can be received
> and displayed in the Textview widget. The program connects to the
> server fine, logs in great. When the user types in the entry box and
> hits send, the program sends the entered message to the server and it
> is then sent to all clients including the author of the message. The
> problem is that the client is not receiving the message from the
> server; I suspect it is the timer. I tried printing text in the loop
> to see if it was still running but it only printed once which could
> mean that it has stopped working. Any ideas on how to remedy this
> problem?
>
> #!/usr/bin/perl
> # Flow of the Program:
> # *Send message to the server - send_msg_all
> # *Connect to the server - sub connect_server
> # -unblock the server - nonblock
> # -Login to the server - send_login
> # -Timer started to wait for messages - wait_for_msg
> # >Handler - handle
> # $Process the incoming messages - process_incoming
> # @Recieve messages and display in textview - rcv_msg_all
>
> use warnings;
> use strict;
> use Gtk2 -init;
> use Glib qw/TRUE FALSE/;
> use IO::Socket::INET;
> use Tie::RefHash;
> use IO::Select;
>
> #global variables
> my $buffer;
> my $host = "Deadpickle-hobo";
> my $port = 6666;
> my $conn_stat = 'idle';
> my %inbuffer = ();
> my %outbuffer = ();
> my %ready = ();
> my $select;
> my $conn;
> my $user;
>
> #the main chat widget
> my $main_window = Gtk2::Window->new("toplevel");
> $main_window->signal_connect(delete_event => sub {Gtk2->main_quit;});
> $main_window->set_default_size(250, 200);
>
> my $table = Gtk2::Table->new(4, 2, FALSE);
>
> $buffer = Gtk2::TextBuffer->new;
> my $button = Gtk2::Button->new("Send");
> my $entry = Gtk2::Entry->new();
>
> my $label = Gtk2::Label->new("Chat Client Test");
>
> my $textview = Gtk2::TextView->new_with_buffer($buffer);
> $textview->set_cursor_visible (FALSE);
> my $swindow = Gtk2::ScrolledWindow->new( undef, undef);
> $swindow->set_policy( 'automatic', 'automatic');
> $swindow->set_shadow_type( 'etched-out');
>
> $swindow->add( $textview);
>
> $table->attach_defaults($label, 0, 1, 0, 1);
> $table->attach_defaults($swindow, 0, 2, 1, 3);
> $table->attach_defaults($entry, 0, 1, 3, 4);
> $table->attach_defaults($button, 1, 2, 3, 4);
> $main_window->add($table);
>
> $main_window->show_all();
>
> $button->signal_connect("clicked" => sub { send_msg_all($entry-
>
> >get_text); $entry->set_text('');} );
>
> #run the login dialog
> dialog($buffer);
>
> Gtk2->main;
>
> #-------------------Login Dialog-------------------
> sub dialog{
> my $buffer = shift;
>
> 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 $dialog_label3 = Gtk2::Label->new('Host:');
> 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);
>
> $dialog_button1->signal_connect("clicked" => sub {$user = $chat_user-
>
> >get_text; $dialog_window->destroy; $buffer->insert(($buffer-
> >get_end_iter), "Username: $user...\n"); connect_server()});
>
> $dialog_window->add($dialog_table);
>
> $dialog_window->show_all;
>
> return 1;}
>
> #------------------Connect to server---------------------
> #establishes connection to the server
> sub connect_server{
> if ($conn_stat ne 'connected') {
> $buffer->insert(($buffer->get_end_iter), "Connecting to Server
> $host:$port...\n");
>
> $conn = IO::Socket::INET->new(PeerAddr => $host, PeerPort =>
> $port, Proto => 'tcp') or popup_err(1);
>
> if ($conn) {
> %inbuffer = ();
> %outbuffer = ();
> %ready = ();
> tie %ready, 'Tie::RefHash';
> nonblock($conn);
> $select = IO::Select->new($conn);
> $conn_stat = 'connected';
> $buffer->insert(($buffer->get_end_iter), "Connected!\n");
>
> #send login to server
> send_login();
>
> #start the timer that monitors incoming messages
> my $timer_waiting = Glib::Timeout->add(100, \&wait_for_msg);
> }
> }}
>
> #-------------------Error popup-------------------
> # pops up an error message
> sub popup_err{
> my ($error_code) = @_;
> my $error;
>
> if ($error_code == 1) {$error = "Cannot create Socket!"}
> elsif ($error_code == 2) {$error = "Username to Short!"}
> elsif ($error_code == 3) {$error = "No connection Established!"}
> elsif ($error_code == 4) {$error = "Already Logged on with This User
> Name!"}
> elsif ($error_code == 5) {$error = "Not Connected!"}
> else {$error = "Unkown Error!"}
>
> $buffer->insert(($buffer->get_end_iter), "$error\n");
>
> my $error_dialog = Gtk2::MessageDialog->new($main_window, 'destroy-
> with-parent', 'error', 'ok', "$error");
>
> $error_dialog->run;
> $error_dialog->destroy;}
>
> #-------------------blocking-------------------
> # nonblock($socket) puts socket into nonblocking mode
> sub nonblock { my $socket = shift; $socket->blocking(0);}
> #-------------------Message Waiting-------------------
> # Wait for incoming messages from the server relayed from clients
> sub wait_for_msg {
>
> if ($conn_stat eq 'connected') {
> my ($list_size, $msg);
> my $server;
> my $rv;
> my $data;
>
> print "waiting..\n";
>
> # check for new information on the connections we have
> # anything to read or accept?
> foreach $server ($select->can_read(1)) {
> # read data
> $data = '';
> $rv = $server->recv($data, 'POSIX::BUFSIZ', 0);
> $inbuffer{$server} .= $data;
>
> # test whether the data in the buffer or the data we
> # just read means there is a complete request waiting
> # to be fulfilled. If there is, set $ready{$client}
> # to the requests waiting to be fulfilled.
> while ($inbuffer{$server} =~ s/(.*\n)//) {
>
> push( @{$ready{$server}}, $1 );
> }
> }
>
> # Any complete requests to process?
> foreach $server (keys %ready) {
>
> handle($server);
> }
> }}
>
> #-------------------Handler-------------------
> # handle($socket) deals with all pending requests for $client
> sub handle {
> # requests are in $ready{$server}
> # send output to $outbuffer{$server}
> my $server = shift;
> my $request;
>
> print "HANDLER WORKING\n";
>
> foreach $request (@{$ready{$server}}) {
> # $request is the text of the request
> # put text of reply into $outbuffer{$client}
> chomp $request;
> process_incoming($server, $request);
> }
> delete $ready{$server};}
>
> #-------------------Process Incoming-------------------
> sub process_incoming {
> my ($server, $msg) = @_;
> my @logged_users;
> my @rcvd_msg = split(/::/, $msg);
>
> if ($rcvd_msg[1] eq "1") {
> if($rcvd_msg[2] eq "03") {
> print "Successfully Logged in!\n";
> } elsif ($rcvd_msg[2] eq "12") {
> popup_err(4);
> } else {
> # Create pop-up for error!
> print "Error Logging in ", $msg, "\n";
> popup_err(5);
> }
> }
> elsif ($rcvd_msg[1] eq "7") {
> # receive global message
> print "$msg\n";
> rcv_msg_all($rcvd_msg[3], $rcvd_msg[4
> } else {
> print "Unrecognized response: $msg\n";
> exit(0);
> }}
>
> #-------------------Send message to all-------------------
> sub send_msg_all {
> my ($msg) = @_;
>
> print "$conn\n";
>
> if(defined $conn) {
> # Send a the Message to server
> print "Sending\n";
> print $conn "7\:\:$user\:\:$msg\n";
> } else {
> popup_err(3);
> }}
>
> #-------------------Send login-------------------
> #logs the user name on the server
> sub send_login {
> # my ($u) = @_;
>
> if(defined $conn) {
> if(length($user) > 0) {
> #send login to server
> print $conn "1\:\:$user\n";
> # update_info();
> } else {
> popup_err(2);
> }
> } else {
> popup_err(3);
> }}
>
> #-------------------Display All Message-------------------
> sub rcv_msg_all {
> my ($from, $msg) = @_;
>
> print "Received Global message:\n";
> if(defined $conn) {
> print "Already Connected: Proceeding with message!\n";
> $buffer->insert(($buffer->get_end_iter), "$from: $msg\n");
> } else {
> print "No connection established!\n";
> popup_err(3);
> }
>
> }

taking the advice I added "return 1" to the end of the subroutines.
The prints in the rcv_msg_all and handle subroutines are not printing
in the terminal so it makes me wounder whether they are actually
running at all. I'm still not receiving any messages into the client
and I cant seem to see why. Course I missed adding "return 1" to the
subs so its probably right in front of me.