Client Program not Receiving Message from Server

D

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);
}
}
 
D

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);
}

}

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top