Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: How to do simultaneous reads and writes to/from a socket?

by BrowserUk (Patriarch)
on May 11, 2006 at 03:30 UTC ( [id://548609]=note: print w/replies, xml ) Need Help??


in reply to How to do simultaneous reads and writes to/from a socket?

This code is not intended as a good example of using threads, but is intended to show how to do bi-directional communications via a single socket under Win32.

It looks a little complicated because it is both client and server:

#! perl -slw use strict; use threads; use IO::Socket; $| = 1; ## The server. async { ## Create the listening port my $server = IO::Socket::INET->new( LocalHost => 'localhost', LocalPort => 9999, Listen => 5, Reuse => 1, ) or die $!; ## Accept connections while( my $client = $server->accept ) { ## Set the socket non-blocking ioctl( $client, 0x8004667e, \1 ) or die $^E; ## Start a thread to receive and display inbound packets async { my $in = ''; while( 1 ) { ## Use to accumulate whatever is available sysread( $client, $in, 100, length( $in ) ); ## When we've accumulated a complete line if( my $p = 1 + index $in, "\n" ) { ## display it and remove it from the buffer printf 'S: %s', substr $in, 0, $p+1, ''; } ## Stop the non-blocking read from running away with t +he cpu Win32::Sleep 100; } }; ## Start another thread to simulate input from other clients async { print $client 'Some text' while sleep 1; }; } }; ## The client ## Connect to the server my $server = IO::Socket::INET->new( 'localhost:9999' ) or die $!; ## Set the socket non-blocking ioctl( $server, 0x8004667e, \1 ); ## Start a thread to recieve and display input from the server async { my $in = ''; while( 1 ) { ## Accumulate input and display when we've got a full line sysread( $server, $in, 100, length( $in ) ); if( my $p = 1 + index $in, "\n" ) { printf 'C: %s', substr $in, 0, $p+1, ''; } Win32::Sleep 100; } }; ## Give the threads a chance to start sleep 2; ## The main thread reads from the keyboard and sends to the server. while( <STDIN> ) { print $server $_; }

NOTE: No 'select' in sight.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: How to do simultaneous reads and writes to/from a socket?
by wavenator (Novice) on Oct 12, 2007 at 08:15 UTC
    the codes have not worked for me . but as i see it's just a server that excepts more then 1 client. am i wrong?
      the codes have not worked for me .

      Oh? How can you tell? What errors did you see?

      but as i see it's just a server that excepts more then 1 client. am i wrong?

      Well actually, it is both client and server all in a single program. This bit (as suggested by the comment) is a multi-threaded, asynchronous, bi-directional server:

      ## The server. async { ## Create the listening port my $server = IO::Socket::INET->new( LocalHost => 'localhost', LocalPort => 9999, Listen => 5, Reuse => 1, ) or die $!; ## Accept connections while( my $client = $server->accept ) { ## Set the socket non-blocking ioctl( $client, 0x8004667e, \1 ) or die $^E; ## Start a thread to receive and display inbound packets async { my $in = ''; while( 1 ) { ## Use to accumulate whatever is available sysread( $client, $in, 100, length( $in ) ); ## When we've accumulated a complete line if( my $p = 1 + index $in, "\n" ) { ## display it and remove it from the buffer printf 'S: %s', substr $in, 0, $p+1, ''; } ## Stop the non-blocking read from running away with t +he cpu Win32::Sleep 100; } }; ## Start another thread to simulate input from other clients async { print $client 'Some text' while sleep 1; }; } };

      And this bit (again, the comment), is a non-blocking bi-directional client with asynchronous keyboard input.

      ## The client ## Connect to the server my $server = IO::Socket::INET->new( 'localhost:9999' ) or die $!; ## Set the socket non-blocking ioctl( $server, 0x8004667e, \1 ); ## Start a thread to recieve and display input from the server async { my $in = ''; while( 1 ) { ## Accumulate input and display when we've got a full line sysread( $server, $in, 100, length( $in ) ); if( my $p = 1 + index $in, "\n" ) { printf 'C: %s', substr $in, 0, $p+1, ''; } Win32::Sleep 100; } }; ## Give the threads a chance to start sleep 2; ## The main thread reads from the keyboard and sends to the server. while( <STDIN> ) { print $server $_; }

      The point of the code is to demonstrate how to achieve asynchronous, bi-directional communications via a single socket. You are then supposed to take that code and use it to understand the way it works and then adapt it to your particular requirements. So far, as far as I have seen in your last two threads, you haven't yet even defined what your requirements are. That's often a sign that you aren't really sure what it is that you want in the first place.

      Several people posted code in you other thread and you seemed to just say that it didn't work for you. Given that I know the quality of the code posted by guys like zentara and others, I know that they don't post non-working code, so the question is why doesn't it work for you?

      For example. Are you looking to allow just two people to talk to each other point to point, or are you looking for something more elaborate?

      So, until you define more clearly what kind of chat program you are trying to write, and demonstrate some propensity to trying to understand the posted code and adapt it to your requirements, it looks very much to me like you are hoping someone will just write the code for you. And if that is the case, why not just download one of the dozens of free IM and IRC programs available and use that?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        k now ill explain all first the error: "cant coerce readonly REF to string in ioctl : line 16" and ill explain what i am trying to do a chat between 2 ppl only!!!! not like irc just 2 ppl that chat each other without blocking thats all simpple to understand

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://548609]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (2)
As of 2024-04-20 03:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found