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

I have wrote an IRC client but am having trouble with it. It doesnt always seem to join the channel and I'm not sure why. In fact the client shows up in the channel when I'm monitoring it with mirc which means that it did join the channel but it is not recieving anything from the server such as another client talking. I'm not sure whats wrong and could use some help.
#!/usr/local/bin/perl -w use strict; use Gtk2 '-init'; use Glib qw/TRUE FALSE/; use IO::Socket; use Gtk2::Helper; use Gtk2::Gdk::Keysyms; my $chat_state = 'Connect'; my $sock; my $channel = "#GRRUVI"; my $nick = "MetBase"; my $irc = "irc.servercentral.net"; my $chat_entry; my $chat_send_sig; my $chat_textview; my $chat_button; my $watch; my $tag; my $job = 3; my $login = $nick; #-------------------Main Loop------------------- &chat_build; Gtk2->main; ####################CHAT BLOCK#################### #-------------------chat Build------------------- sub chat_build { my $chat_window = Gtk2::Window->new('toplevel'); $chat_window->set_title('Chat Client'); $chat_window->set_position('center'); $chat_window->set_default_size( 300, 300 ); $chat_window->signal_connect(delete_event=> sub{ if (defined $sock){ close $sock; $chat_state='Connect'; Gtk2::Helper->remove_watch($watch); Gtk2->main_quit; }; return FALSE; }); $chat_entry = Gtk2::Entry->new; my $chat_vbox = Gtk2::VBox->new; if ($job != 2){ my $menu_edit = Gtk2::Menu->new(); $menu_edit->append(Gtk2::TearoffMenuItem->new); if ($job == 1){ my $shortcut1 = Gtk2::MenuItem->new('Ctrl+C = Confirm Visu +al: Aircraft'); my $shortcut2 = Gtk2::MenuItem->new('Ctrl+L = Lost Visual: + Aircraft'); my $shortcut3 = Gtk2::MenuItem->new('Ctrl+P = Potential Co +nflict: Aircraft'); my $shortcut4 = Gtk2::MenuItem->new('Ctrl+N = No Visual: A +ircraft'); $shortcut1->signal_connect('activate' => sub {$chat_entry- +>set_text('Confirm Visual: Aircraft '); $chat_entry->set_position(25) +}); $shortcut2->signal_connect('activate' => sub {$chat_entry- +>set_text('Lost Visual: Aircraft '); $chat_entry->set_position(22)}); $shortcut3->signal_connect('activate' => sub {$chat_entry- +>set_text('Potential Conflict: Aircraft '); $chat_entry->set_position +(29)}); $shortcut4->signal_connect('activate' => sub {$chat_entry- +>set_text('No Visual: Aircraft '); $chat_entry->set_position(20)}); $menu_edit->append($shortcut1); $menu_edit->append($shortcut2); $menu_edit->append($shortcut3); $menu_edit->append($shortcut4); } if ($job == 3){ my $shortcut1 = Gtk2::MenuItem->new('Ctrl+M = Mandatory 1 +minute query: All spotters report status'); my $shortcut2 = Gtk2::MenuItem->new('Ctrl+L = Loss of visu +al 30 sec query: All spotters report status'); my $shortcut3 = Gtk2::MenuItem->new('Ctrl+D = Dual visual +contact confirmed: Aircraft'); my $shortcut4 = Gtk2::MenuItem->new('Ctrl+C = LOST VISUAL +CONTINGENCY INITIATED: Aircraft'); my $shortcut5 = Gtk2::MenuItem->new('Ctrl+E = EMERGENCY LA +NDING CONTINGENCY INITIATED: Aircraft'); $shortcut1->signal_connect('activate' => sub {$chat_entry- +>set_text('Mandatory 1 minute query: All spotters report status '); $ +chat_entry->set_position(53)}); $shortcut2->signal_connect('activate' => sub {$chat_entry- +>set_text('Loss of visual 30 sec query: All spotters report status ') +; $chat_entry->set_position(56)}); $shortcut3->signal_connect('activate' => sub {$chat_entry- +>set_text('Dual visual contact confirmed: Aircraft '); $chat_entry->s +et_position(40)}); $shortcut4->signal_connect('activate' => sub {$chat_entry- +>set_text('LOST VISUAL CONTINGENCY INITIATED: Aircraft '); $chat_entr +y->set_position(44)}); $shortcut5->signal_connect('activate' => sub {$chat_entry- +>set_text('EMERGENCY LANDING CONTINGENCY INITIATED: Aircraft '); $cha +t_entry->set_position(50)}); $menu_edit->append($shortcut1); $menu_edit->append($shortcut2); $menu_edit->append($shortcut3); $menu_edit->append($shortcut4); $menu_edit->append($shortcut5); } my $menu_item_edit= Gtk2::MenuItem->new('_Shortcuts'); $menu_item_edit->set_submenu ($menu_edit); my $menu_bar = Gtk2::MenuBar->new; $menu_bar->append($menu_item_edit); $chat_vbox->pack_start( $menu_bar, FALSE, FALSE, 0 ); } my $chat_scroll = Gtk2::ScrolledWindow->new; $chat_scroll->set_shadow_type( 'etched-out'); $chat_textview = Gtk2::TextView->new; #$chat_entry = Gtk2::Entry->new; my $chat_buffer = $chat_textview->get_buffer; $chat_buffer->create_mark( 'end', $chat_buffer->get_end_iter, FALS +E ); $chat_buffer->signal_connect(insert_text => sub { $chat_textview->scroll_to_mark( $chat_buffer->get_mark('end'), + 0.0, TRUE, 0, 0.5 ); }); $chat_button = Gtk2::Button->new; $chat_button->set_label($chat_state); # allows for sending each line with an enter keypress $chat_send_sig = $chat_entry->signal_connect ('key-press-event' => + sub { my ($widget,$event)= @_; if( $event->keyval() == 65293){ # a return key press my $text = $chat_entry->get_text; if(defined $sock){ print $sock "PRIVMSG $channel :$tex +t\r\n";} $chat_entry->set_text(''); $chat_entry->set_position(0); post($nick, $text); } }); $chat_entry->signal_handler_block($chat_send_sig); #not connected +yet $chat_entry->set_editable(0); $chat_textview->set_editable(0); $chat_textview->set_cursor_visible(0); $chat_textview->set_wrap_mode('word'); $chat_scroll->add($chat_textview); $chat_vbox->add($chat_scroll); $chat_vbox->pack_start( $chat_entry, FALSE, FALSE, 0 ); $chat_vbox->pack_start( $chat_button, FALSE, FALSE, 0 ); $chat_window->add($chat_vbox); $chat_window->show_all; $chat_button->signal_connect("clicked" => sub { if ($chat_state eq 'Connect') { $chat_button->set_label('Disconnect'); $chat_state='Disconnect'; &connecting; } else { $chat_button->set_label('Connect'); $chat_state='Connect'; &disconnecting; } }); #capures the shortcuts if ($job == 1){ my @chat_accels = ( #Spotter only #Confirm Aircraft 1-5 {key => 'C', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Confirm Visual: Aircraft "); $chat_entry->set_positi +on(25)}}, #Lost Aircraft 1-5 {key => 'L', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Lost Visual: Aircraft "); $chat_entry->set_position( +22)}}, #Potential Conflict Aircraft 1-5 {key => 'P', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Potential Conflict: Aircraft "); $chat_entry->set_po +sition(29)}}, #No visual Aircraft 1-5 {key => 'N', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("No Visual: Aircraft "); $chat_entry->set_position(20 +)}} ); my $chat_accel_group = Gtk2::AccelGroup->new; foreach my $a (@chat_accels) { $chat_accel_group->connect ($Gtk2::Gdk::Keysyms{$a->{key}} +, $a->{mod}, 'visible', $a->{func}); } $chat_window->add_accel_group ($chat_accel_group); }; if ($job == 3){ my @chat_accels = ( #Met Base #Manditory query {key => 'M', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Mandatory 1 minute query: All spotters report status + "); $chat_entry->set_position(53)}}, #Loss of Visual {key => 'L', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Loss of visual 30 sec query: All spotters report sta +tus "); $chat_entry->set_position(56)}}, #Dual visual contact confirmed {key => 'D', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Dual visual contact confirmed: Aircraft "); $chat_en +try->set_position(40)}}, #LoV Contigency initiated 1-5 {key => 'C', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("LOST VISUAL CONTINGENCY INITIATED: Aircraft "); $cha +t_entry->set_position(44)}}, #Emergency Landing {key => 'E', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("EMERGENCY LANDING CONTINGENCY INITIATED: Aircraft ") +; $chat_entry->set_position(50)}} ); my $chat_accel_group = Gtk2::AccelGroup->new; foreach my $a (@chat_accels) { $chat_accel_group->connect ($Gtk2::Gdk::Keysyms{$a->{key}} +, $a->{mod}, 'visible', $a->{func}); } $chat_window->add_accel_group ($chat_accel_group); #open chat output file: month day hour minute second if ($job == 3){ my @time = gmtime; my $m = $time[4]+1; my $d = $time[3]; my $h = $time[2]; my $mi = $time[1]; my $s = $time[0]; $m = "0$m" if $m < 9; $d = "0$d" if $d < 9; $h = "0$h" if $h < 9; $mi = "0$mi" if $mi < 9; $s = "0$s" if $s < 9; my $output = "$m$d$h$mi$s"; open(CHAT,'>', $output); } }; return; } #-------------------Connect to IRC Server------------------- sub connecting { # Connect to the IRC server. $sock = new IO::Socket::INET( PeerAddr => $irc, PeerPort => 6667, Proto => 'tcp', ) or die "Can't connect\n"; if (defined $sock){ my $sys_msg = "Connected to $irc ..."; post($nick, $sys_msg); } # Log on to the server. print $sock "NICK $nick\r\n"; print $sock "USER $login 8 * :CoCoNUE Member\r\n"; # Read lines from the server until it tells us we have connected. while (my $input = <$sock>) { print "$input\n"; # Check the numerical responses from the server. if ($input =~ /004/) { # We are now logged in. my $sys_msg = "Logged in to $irc ..."; post($nick, $sys_msg); #sleep 2; print "joining\n"; print $sock "/JOIN $channel\r\n"; $watch = Gtk2::Helper->add_watch( fileno $sock, 'in', \&in +coming_data, $sock ); print "joined\n" if defined $watch; $chat_entry->set_editable(1); $chat_entry->grab_focus; $chat_entry->signal_handler_unblock ($chat_send_sig); last; } elsif ($input =~ /433/) { my $sys_msg = "Nickname is already in use"; post($nick, $sys_msg); &disconnecting; #last; return FALSE; } } return; Gtk2->main_iteration while Gtk2->events_pending; } #-------------------Disconnect from Server and End Watch-------------- +----- sub disconnecting { Gtk2::Helper->remove_watch($watch) if defined $watch; print $sock "QUIT\r\n"; close $sock; $chat_entry->signal_handler_block($chat_send_sig); $chat_state = 'Connect'; $chat_button->set_label($chat_state); my $sys_msg = 'Disconnected!!!!'; post($nick, $sys_msg); print "Disconnected\n"; return 0; } #-------------------Watch for IRC Inputs------------------- sub incoming_data { my ( $fd, $condition, $fh ) = @_; print "its going\n"; if ( $condition eq 'in' ) { my $input; sysread $fh, $input, 1000000; chop $input; print "$input\n"; if ($input =~ /^PING(.*)$/i) { # We must respond to PINGs to avoid being disconnected. print $sock "PONG $1\r\n"; } elsif ($input =~ m/PRIVMSG\s($channel)/i) { print "happy $input\n"; my @sender = split(/!/, $input); my @message = split(/:/, $input); my $length = length($sender[0]); my $who = substr($sender[0], 1, $length); post($who, $message[2]); } elsif ($input =~ m/QUIT/i) { print "$input\n"; my @sender = split(/!/, $input); my $length = length($sender[0]); my $who = substr($sender[0], 1, $length); my $sys_msg = "$who has QUIT!"; post($who, $sys_msg); } elsif ($input =~ m/JOIN/i) { print "$input\n"; my @sender = split(/!/, $input); my $length = length($sender[0]); my $who = substr($sender[0], 1, $length); my $sys_msg = "$who has JOINED $channel!"; post($who, $sys_msg); } elsif ($input =~ m/353\s($nick)/i) { print "sad $input\n"; my @message = split(/:/, $input); if ($input =~ m/MODE/) { print "mode $input\n"; chop $message[5]; my $sys_msg = "Logged in users are->$message[5]"; post($nick, $sys_msg); } else{ print "not moded $input\n"; chop $message[2]; my $sys_msg = "Logged in users are->$message[2]"; post($nick, $sys_msg); } } else{ #print "$input\n"; } } return TRUE; } #-------------------Post messages in the Window------------------- sub post{ my ($name, $msg) = @_; my @time = gmtime; my $hour = $time[2]; my $min = $time[1]; my $sec = $time[0]; $hour = "0$time[2]" if $time[2] < 10; $min = "0$time[1]" if $time[1] < 10; $sec = "0$time[0]" if $time[0] < 10; my $post_time = "($hour:$min:$sec)"; my $chat_buffer = $chat_textview->get_buffer; print "$name\n"; print "$nick\n"; if ($name ne $nick){ $chat_buffer->insert_with_tags( $chat_buffer->get_end_iter, "$ +name $post_time: $msg\n", $chat_buffer->create_tag($tag, foreground=> +'red')); } else{ $chat_buffer->insert( $chat_buffer->get_end_iter, "$name $post +_time: $msg\n" ); } #Save MET chat output to a file on Local Machine print CHAT "$name $post_time: $msg\n" if $job == 3; }

Replies are listed 'Best First'.
Re: IRC Client not Joining Channel
by ambrus (Abbot) on Mar 04, 2008 at 08:30 UTC

    Two questions.

    1. Have you written that all at once or in small parts, verifying that each small chunk works. If all at once, don't be surprised it doesn't work, and especially don't exepct us to just read it all through and find all bugs. If in parts, can you give us hints in what part of the code you're sure works and what might not?

    2. In

    print $sock "/JOIN $channel\r\n";
    why the fuck are you sending that slash?

    Update: 3. also, are you sure that input handler will not read more than one lines at once and treat them as a single line? Or what about partial lines? Also, use proper regexps so you don't pick up a random word snippet like QUIT somewhere inside a message. Try something like /^(?::\S+\s+)QUIT/ or something. Or better, parse the line to source, command, and argument list properly.

Re: IRC Client not Joining Channel
by quester (Vicar) on Mar 04, 2008 at 06:38 UTC
    You could look at the actual TCP/IP traffic between the client and the server with wireshark. This would tell you whether the server is sending the data, and whether it is formatted the way you expect.
Re: IRC Client not Joining Channel
by moritz (Cardinal) on Mar 04, 2008 at 07:49 UTC
    Instead of reinventing the wheel, you should use an existing cpan module for dealing with IRC.

    Currently POE::Component::IRC is a recommended standard (though I use the simpler interface Bot::BasicBot for it), but it forces you to use the POE framework.

    If you don't want that, you can use Net::IRC. I don't know if that's maintained anymore, but it's surely more stable than your IRC handling code ;-)

      Parse::IRC is currently the best IRC parsing module.
        And what would you recommend for sending messages and managing connections? It seems that is a problem as well ;-)
Re: IRC Client not Joining Channel
by assemble (Friar) on Mar 04, 2008 at 14:29 UTC

    As mentioned before, you need to do a much better job of parsing the IRC protocol. Your current methods would fail if you were in a channel and somebody sent a simple message such as 'QUIT, you oddball parser!'

    At one point in the past, I wrote my own IRC bot just to prove to myself that I could, but the protocol is really just plain nasty, and it took a lot of reverse engineering via wireshark (then called ethereal) because I didn't find the RFC particularly helpful.

    The key problem with your code has been mentioned by ambrus. There should not be any slashes in the commands you send to the server. That is the first clue. I believe the join command will probably work if you simply remove the leading '/' on the command.

    I'd recommend looking at this Parse::Irc module. It does most of the dirty work of parsing, and looks pretty nice. I don't really know about those other modules, but unless your goal is to learn about network communications and the IRC protocol, I'd recommend using one of them.

      Wow thanks for all the replies.
      The program I wrote still will enter the room if the slash is removed (but it will not say that) but it seems like the Helper is not working correctly. With all these problems I decided to go with the suggested Parse::IRC module to make this a little easier. Right now I'm just trying to get it to connect in a GTK2 environment and print out text in the terminal but I cant get it to do that. I think the problem is in the incoming_data sub or near there. any ideas?
      #!/usr/bin/perl -w use strict; use Gtk2 '-init'; use Glib qw/TRUE FALSE/; use Gtk2::Gdk::Keysyms; use IO::Socket; use Gtk2::Helper; use Parse::IRC; #Global Variables my $sock; my $chat_textview; my $chat_entry; my $chat_send_sig; my $nick = "LOVERMET"; my $chat_state = 'Connect'; my $chat_button; my $watch; my $tag; my $login = $nick; my $job = 3; my $channel = "#GRRUVI"; my $irc = "irc.servercentral.net"; my $parser = Parse::IRC->new(public => 1); my %dispatch = ('001' => \&irc_001); #-------------------Main Loop------------------- &chat_build; Gtk2->main; ####################CHAT BLOCK#################### #-------------------chat Build------------------- sub chat_build { my $chat_window = Gtk2::Window->new('toplevel'); $chat_window->set_title('Chat Client'); $chat_window->set_position('center'); $chat_window->set_default_size( 300, 300 ); $chat_window->signal_connect(delete_event=> sub{ if (defined $sock){ close $sock; $chat_state='Connect'; Gtk2::Helper->remove_watch($watch); }; return FALSE; }); $chat_entry = Gtk2::Entry->new; my $chat_vbox = Gtk2::VBox->new; if ($job != 2){ my $menu_edit = Gtk2::Menu->new(); $menu_edit->append(Gtk2::TearoffMenuItem->new); if ($job == 1){ my $shortcut1 = Gtk2::MenuItem->new('Ctrl+C = Confirm Visu +al: Aircraft'); my $shortcut2 = Gtk2::MenuItem->new('Ctrl+L = Lost Visual: + Aircraft'); my $shortcut3 = Gtk2::MenuItem->new('Ctrl+P = Potential Co +nflict: Aircraft'); my $shortcut4 = Gtk2::MenuItem->new('Ctrl+N = No Visual: A +ircraft'); $shortcut1->signal_connect('activate' => sub {$chat_entry- +>set_text('Confirm Visual: Aircraft '); $chat_entry->set_position(25) +}); $shortcut2->signal_connect('activate' => sub {$chat_entry- +>set_text('Lost Visual: Aircraft '); $chat_entry->set_position(22)}); $shortcut3->signal_connect('activate' => sub {$chat_entry- +>set_text('Potential Conflict: Aircraft '); $chat_entry->set_position +(29)}); $shortcut4->signal_connect('activate' => sub {$chat_entry- +>set_text('No Visual: Aircraft '); $chat_entry->set_position(20)}); $menu_edit->append($shortcut1); $menu_edit->append($shortcut2); $menu_edit->append($shortcut3); $menu_edit->append($shortcut4); } if ($job == 3){ my $shortcut1 = Gtk2::MenuItem->new('Ctrl+M = Mandatory 1 +minute query: All spotters report status'); my $shortcut2 = Gtk2::MenuItem->new('Ctrl+L = Loss of visu +al 30 sec query: All spotters report status'); my $shortcut3 = Gtk2::MenuItem->new('Ctrl+D = Dual visual +contact confirmed: Aircraft'); my $shortcut4 = Gtk2::MenuItem->new('Ctrl+C = LOST VISUAL +CONTINGENCY INITIATED: Aircraft'); my $shortcut5 = Gtk2::MenuItem->new('Ctrl+E = EMERGENCY LA +NDING CONTINGENCY INITIATED: Aircraft'); $shortcut1->signal_connect('activate' => sub {$chat_entry- +>set_text('Mandatory 1 minute query: All spotters report status '); $ +chat_entry->set_position(53)}); $shortcut2->signal_connect('activate' => sub {$chat_entry- +>set_text('Loss of visual 30 sec query: All spotters report status ') +; $chat_entry->set_position(56)}); $shortcut3->signal_connect('activate' => sub {$chat_entry- +>set_text('Dual visual contact confirmed: Aircraft '); $chat_entry->s +et_position(40)}); $shortcut4->signal_connect('activate' => sub {$chat_entry- +>set_text('LOST VISUAL CONTINGENCY INITIATED: Aircraft '); $chat_entr +y->set_position(44)}); $shortcut5->signal_connect('activate' => sub {$chat_entry- +>set_text('EMERGENCY LANDING CONTINGENCY INITIATED: Aircraft '); $cha +t_entry->set_position(50)}); $menu_edit->append($shortcut1); $menu_edit->append($shortcut2); $menu_edit->append($shortcut3); $menu_edit->append($shortcut4); $menu_edit->append($shortcut5); } my $menu_item_edit= Gtk2::MenuItem->new('_Shortcuts'); $menu_item_edit->set_submenu ($menu_edit); my $menu_bar = Gtk2::MenuBar->new; $menu_bar->append($menu_item_edit); $chat_vbox->pack_start( $menu_bar, FALSE, FALSE, 0 ); } my $chat_scroll = Gtk2::ScrolledWindow->new; $chat_scroll->set_shadow_type( 'etched-out'); $chat_textview = Gtk2::TextView->new; #$chat_entry = Gtk2::Entry->new; my $chat_buffer = $chat_textview->get_buffer; $chat_buffer->create_mark( 'end', $chat_buffer->get_end_iter, FALS +E ); $chat_buffer->signal_connect(insert_text => sub { $chat_textview->scroll_to_mark( $chat_buffer->get_mark('end'), + 0.0, TRUE, 0, 0.5 ); }); $chat_button = Gtk2::Button->new; $chat_button->set_label($chat_state); # allows for sending each line with an enter keypress $chat_send_sig = $chat_entry->signal_connect ('key-press-event' => + sub { my ($widget,$event)= @_; if( $event->keyval() == 65293){ # a return key press my $text = $chat_entry->get_text; if(defined $sock){ print $sock "PRIVMSG $channel :$tex +t\r\n";} $chat_entry->set_text(''); $chat_entry->set_position(0); post($nick, $text); } }); $chat_entry->signal_handler_block($chat_send_sig); #not connected +yet $chat_entry->set_editable(0); $chat_textview->set_editable(0); $chat_textview->set_cursor_visible(0); $chat_textview->set_wrap_mode('word'); $chat_scroll->add($chat_textview); $chat_vbox->add($chat_scroll); $chat_vbox->pack_start( $chat_entry, FALSE, FALSE, 0 ); $chat_vbox->pack_start( $chat_button, FALSE, FALSE, 0 ); $chat_window->add($chat_vbox); $chat_window->show_all; $chat_button->signal_connect("clicked" => sub { if ($chat_state eq 'Connect') { $chat_button->set_label('Disconnect'); $chat_state='Disconnect'; &connecting; } else { $chat_button->set_label('Connect'); $chat_state='Connect'; &disconnecting; } }); #capures the shortcuts if ($job == 1){ my @chat_accels = ( #Spotter only #Confirm Aircraft 1-5 {key => 'C', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Confirm Visual: Aircraft "); $chat_entry->set_positi +on(25)}}, #Lost Aircraft 1-5 {key => 'L', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Lost Visual: Aircraft "); $chat_entry->set_position( +22)}}, #Potential Conflict Aircraft 1-5 {key => 'P', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Potential Conflict: Aircraft "); $chat_entry->set_po +sition(29)}}, #No visual Aircraft 1-5 {key => 'N', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("No Visual: Aircraft "); $chat_entry->set_position(20 +)}} ); my $chat_accel_group = Gtk2::AccelGroup->new; foreach my $a (@chat_accels) { $chat_accel_group->connect ($Gtk2::Gdk::Keysyms{$a->{key}} +, $a->{mod}, 'visible', $a->{func}); } $chat_window->add_accel_group ($chat_accel_group); }; if ($job == 3){ my @chat_accels = ( #Met Base #Manditory query {key => 'M', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Mandatory 1 minute query: All spotters report status + "); $chat_entry->set_position(53)}}, #Loss of Visual {key => 'L', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Loss of visual 30 sec query: All spotters report sta +tus "); $chat_entry->set_position(56)}}, #Dual visual contact confirmed {key => 'D', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("Dual visual contact confirmed: Aircraft "); $chat_en +try->set_position(40)}}, #LoV Contigency initiated 1-5 {key => 'C', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("LOST VISUAL CONTINGENCY INITIATED: Aircraft "); $cha +t_entry->set_position(44)}}, #Emergency Landing {key => 'E', mod => 'control-mask', func => sub {$chat_ent +ry->append_text("EMERGENCY LANDING CONTINGENCY INITIATED: Aircraft ") +; $chat_entry->set_position(50)}} ); my $chat_accel_group = Gtk2::AccelGroup->new; foreach my $a (@chat_accels) { $chat_accel_group->connect ($Gtk2::Gdk::Keysyms{$a->{key}} +, $a->{mod}, 'visible', $a->{func}); } $chat_window->add_accel_group ($chat_accel_group); #open chat output file: month day hour minute second if ($job == 3){ my @time = gmtime; my $m = $time[4]+1; my $d = $time[3]; my $h = $time[2]; my $mi = $time[1]; my $s = $time[0]; $m = "0$m" if $m < 9; $d = "0$d" if $d < 9; $h = "0$h" if $h < 9; $mi = "0$mi" if $mi < 9; $s = "0$s" if $s < 9; my $output = "$m$d$h$mi$s"; open(CHAT,'>', $output); } }; return; } #-------------------Connect to IRC Server------------------- sub connecting { # Connect to the IRC server. $sock = new IO::Socket::INET( PeerAddr => $irc, PeerPort => 6667, Proto => 'tcp', ) or die "Can't connect\n"; # Log on to the server. print $sock "NICK $nick\r\n"; print $sock "USER $login 8 * :CoCoNUE Member\r\n"; $watch = Gtk2::Helper->add_watch( fileno $sock, 'in', \&in +coming_data, $sock ); $chat_entry->set_editable(1); $chat_entry->grab_focus; $chat_entry->signal_handler_unblock ($chat_send_sig); Gtk2->main_iteration while Gtk2->events_pending; return 1; } #-------------------Watch for IRC Inputs------------------- sub incoming_data { my ( $fd, $condition, $fh ) = @_; print "its going\n"; if ( $condition eq 'in' ) { my $input; sysread $fh, $input, 1000000; #chop $input; $input =~ s/\r\n//g; my $hashref = $parser->parse( $input ); SWITCH: { my $type = lc $hashref->{command}; my @args; push @args, $hashref->{prefix} if $hashref->{prefix}; push @args, @{ $hashref->{params} }; if ( defined $dispatch{$type} ) { $dispatch{$type}->(@args); last SWITCH; } print STDOUT join( ' ', "irc_$type:", @args ), "\n"; } } return 1; } sub irc_001 { print STDOUT "Connected to $_[0]\n"; print $sock "JOIN $channel\r\n"; return 1; }
        I recommend cutting out all the extra code next time, it is very distracting from the actual problem. So here is the code that you say appears to be bad
        #-------------------Watch for IRC Inputs------------------- sub incoming_data { my ( $fd, $condition, $fh ) = @_; print "its going\n"; if ( $condition eq 'in' ) { my $input; sysread $fh, $input, 1000000; #chop $input; $input =~ s/\r\n//g; my $hashref = $parser->parse( $input ); SWITCH: { my $type = lc $hashref->{command}; my @args; push @args, $hashref->{prefix} if $hashref->{prefix}; push @args, @{ $hashref->{params} }; if ( defined $dispatch{$type} ) { $dispatch{$type}->(@args); last SWITCH; } print STDOUT join( ' ', "irc_$type:", @args ), "\n"; } } return 1; }
        First, I recommend changing:
        sysread $fh, $input, 1000000; #chop $input; $input =~ s/\r\n//g;
        to:
        $input = <$fh>; chomp $input;
        You can put a loop in there if you want to handle more than one line at a time. What you are doing mushes everything together and makes it unparseable.