Hiya everyone. Just thought that maybe someone could help me out on this one.
I'm making a client on perl using IO::Socket and it works for most of my apps.
But i came upon a bit of a challenge here. Everything works fine. I'm sending the login packet to YCHT perfectly and yahoo is logging me in on the chat server. The problem is i only get my reply when yahoo logs me off. Im replying to every SYN/ACK resplies of yahoo server but still i dont get my data in real time. I end up getting the messenger info, chat room info after it logs me off and drops the connection.
here's the code(Full source not included..... sloppy packet encryption, too shy to post, LMAO!!)
Now i dont have a problem like this on my IRC client which uses the same format though.
Could it be i'm missing something???

sub ychat() {

	my $packet=$_[0];

	my $packlen=$_[1];
	my $packhand=$_[2];
	my $ycht='jcs.chat.dcn.yahoo.com';

	my $chtport=8001;

           if ($packet,$packlen,$packhand){
	my $whole_packet=YCHT->create_packet($packet,$packlen,$packhand); 
                             if ($whole_packet ne 'VALID') {
                              die "$whole_packet \n";
                              }
          
        }
        else{
         die "Missing ARGS\n";
         }

	###Start connection to chat server  ####

		print "trying to connect to $ycht\n";

		my $chat=IO::Socket::INET->new(
		PeerHost=>$ycht,
                PeerPort=>$chtport,
                Proto=>'tcp',
		SockPort=>3505,
                ) || die "could not connect to chat server\n";


		$chat->autoflush(1);
		print STDERR "connection established\nsending data\n";
		print $chat $whole_packet;
		print STDERR "data sent waiting for reply\n";
		while(defined($incoming=<$chat>)) {
                        ##This will slow me down, but i need the packets in real time.
			while(sysread($incoming,$byte,2)==1) {
			print STDOUT "got reply \n";
			print "$byte\n";
			close $chat;

		}
	       }
	return;
	


}

anyways, anyone got an idea on what im missing ?

Recommended Answers

All 5 Replies

It's always hard when trying to do socket programming that's meant to be event driven, in a procedural fashion. I would personally suggest looking into modules that allow a Perl Application to Act more like it's event driven. Something along the lines of POE or Select. I realize that having built an app this far, having to take it back to the drawing board can be a pain, but that would be the best thing to do.

It would also seem to me, that the loop that you are running is blocking while waiting for data on the socket (The Parent Loop), so it should just sit there until there is data, but the problem is that <> waits for a termination character (\n), or a buffer size. You could also looking Poll, which will tell you if there is data waiting to be read. One thing I tinkered with, was changing $|, so that filehandles wouldn't buffer, but I had no such luck with it.... something maybe you want to dig into. Sorry I can't be of more assistance, but the best solution is to use POE or Select(). Good Luck, and please post the solution you come up with.

ok thanks. I didn't know <> waits for an LF.
But i thought thats what " sysread($incoming,$byte,2)==1) " was supposed to accomplish.
Or does that only work if i use binmode() ?? *never mind i tried right before i posted :D*
Right now i have tried forking a child process, but still nothing. But ethereal is still detecting the packets i receive. :cheesy:
Anyways, yeah it would suck to go back to the drawing boards. But i guess if this it would be alright. the other modules are working already.

Anyways i'll be looking into those modules you referred to. Thanks by the way, i little help is better than nothing ;)
And yeah i'll post the source here when i finish this. I'll even to have your name on the credits if i ever build the guts to upload the modules i use in it to CPAN, :D

well ok. I think i tried POE and select already. And you're right. I might have to go back to the drawing boards with POE. I tried select but its nothing much more different than using fork()
Anyway, as far as windows is concerned i did figure out a way. cause i checked and my (<$chat>) really blocks everything even when i used select. (Unable to post the script i used cause im on windows right now. Anyways, i figured i'd go use VB for the yahoo socket. Then i make a simple socket server with perl, and make the VB app catch the packets, drop em to the perl socket server with a vbcrLF. meaning i get a \n. So i guess i got an easier answer. Easy handling of the socket to yahoo with VB and easy parsing with perl. :D
This might not be permanent though, cause i would still love to finish this project all written in perl. :cheesy: Besides, i dont want those modules i made to go to waste cause they're packet handlers that already works. It's just the darn socket.
I'll still try that POE module sometime soon. thanks for the reference again. But it's too much work as of now, especially when i need some working result and energize my enthusiasm:cheesy:
Select wont work cause it still gets stuck even if i give it a TIMEOUT. I'm still wondering why its blocking even if i add a timeout.
I'll post the one i made with select when i reboot. I'm still running listening to music as of now, in which my soundcard is unsupported by Linux :cheesy:

K. The thing is, so long as you use <> it's probably going to block. Another alternative to consider (while I love your VB to Perl Idea... be forewarned that it would be easier to teach a cat to code ASM In Linux, than to make VB and Perl talk with sockets. I'm not saying it isn't possible, and I'm telling you I love the idea.... but it's not going to be the easiest thing you'll ever do). Another thing to consider is to replace <filehandle> with a sysread call in your while, and then read in 1 byte at a time. Everytime you read a byte, append it to buffer variable, that will contain the entire packet (byte for byte) until you reach the end of your packet (either by knowing the size in bytes, or by knowing a termination character). Then, once you have read in the entire packet, just pass it as a parameter to a sub that will analyze, and respond to the packet. This is where select would come in handy, because a while with sysread isn't going to block... if there is no data, it's just going to skip the while loop. Another alternative to that, is to do a while loop with 1

while (1) {
  # /* Do Socket Stuff */
}

And then just keep trying to read from the socket with your sysread call of 1 byte. If there is data in the socket, you will get that byte, append it to your buffer variable, and then if the length (or termination character) is there, pass it to your procedure that will handle the packet. Let me know what you think...

Actually i did get started on the VB socket right after i posted that message. It's working fine. not that fast as it would be if it was all perl, but it works.
The VB app just handles the socket to the yahoo server which works like magic. Then i start a socket locally that makes every packet from yahoo send to the perl socket but with a vbCrlf which never blocks my while loop. But i gotta try and use Tk for the outputs cause its hard to read on the console. And using VB to update the messages on chatrooms just makes it super slow. Anyways, i also created a linux version of this. It actually worked to the point i send my own packets with the perl script to yahoo. But still no receiving end. For now the linux version relies on zinc's (Yahoo chat client written in python with a bit of editing on the source) log file which is actually a fifo which the perl app uses and gets inputs from. Downside is i'll have to login to yahoo with 2 clients instead of just one.
The one on windows with VB does stand alone and connects without dependencies but slower. But yes i haven't tried the while(1) loop. I did try *select, and using *sysread($handle,$byte,1); to no avail. I also tried using binmode($handle) right after opening the socket and before doing anything with the socket, but it didn't make a difference. I also made another demo using Perl::Tk but im not yet finished with that one (And still blocks). Anyways, i really do appreciate all the support i got here. Thanks for replying to the thread. I kinda get encouraged to do more with feedback. hehe!! :D
Anyways... the codes are still sloppy. but i'm almost finished with re-writing the code. But now that you gave me another idea, hehe. might take longer. Promise that this will be the first place i post the source code both versions when i get done, hehe ;)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.