in reply to Async socket connection

I don't understand your specification.

You talk about "client" and "server", but later on talk about "PC1" and "PC2". Is "PC1" a client or a server, or should "PC1" be both, client and server? (then, it would be neither)

If you mean that PC1 should have one socket for incoming connections on port 8010 and one port for outgoing connections to port 8000, this still doesn't show me what the TCP connections between the two machines PC1 and PC2 would look like. Maybe you can draw a diagram of the machines, open listening ports and which machine connects to which machine from/to which port.

I don't understand the flow of your ADD, STAT and RESP messages. I think it would make things clearer if you show not only which machine sends them but also over which TCP connection(s) the messages are sent. Also, you mention closing connections, which makes the protocol sound even weirder, but maybe showing a sequence diagram here makes things clearer for me.

As for implementing the communication, I am somewhat fond of using Future nowadays as that allows me to mostly avoid the callback hell.

A bit more low-level would be AnyEvent or Net::Async or maybe POE for handling the multiplexing of sockets.

If you want to implement your own multiplexing (which I don't really recommend except as a learning exercise), have a look at IO::Select and then select.

Replies are listed 'Best First'.
Re^2: Async socket connection
by ljamison (Sexton) on Feb 08, 2017 at 20:56 UTC

    Hello, thank you for your input and sorry for the confusion! I have updated the specification to hopefully better reflect the situation.

    1. I have duplicated the diagram which specifies the relationship here
    2. The message in the diagram would be the ADD command
    3. The acknowledgement in the diagram would be the RESP reply
    4. The STAT is only sent FROM PC2 TO PC1
    5. The RECEIVE of both PC1 and PC2 are required to always be listening

    Currently I'm able to run both independently (i.e. server.pl and client.pl) but the BIGGEST problem I face is for both server and client of PC1 to interact with one another which I have not been able to accomplish yet. Right now, they function correctly independently. Ideally, I would like to compress both client and server into one script though from my investigations it appears that would not be as easy (however I've had limited success using Brian D Foy's Modulino pattern).

    Thank you again for your input and any additional comments/suggestions would be welcomed!

      For completeness, I'll replicate the drawing here, just in case that other resource goes away:

      (port 8000) "SEND" PC1 (port 8010) "RECEIVE" | | v ADD ^ | | (port 8000) "RECEIVE" PC2 (port 8010) "SEND"
      (port 8000) "SEND" PC1 (port 8010) "RECEIVE" | | ^ ACK ^ | | (port 8000) "RECEIVE" PC2 (port 8010) "SEND"
      (port 8000) "SEND" PC1 (port 8010) "RECEIVE" | | v ^ STAT | | (port 8000) "RECEIVE" PC2 (port 8010) "SEND"

      From that diagram resp. my interpretation of it, you don't have "SEND" and "RECEIVE" sockets, but some sockets that are listening for and accepting incoming socket connections, and some sockets that are used to talk to the listening sockets. The listening sockets are listening on port 8000 (PC2) and port 8010 (PC1).

      You also use the terms "server" and "client", even though that distinction seems somewhat arbitrary to me because both machines seemm to be able to initiate connections to each other.

      I'm not clear on whether your current two programs client.pl and server.pl are running on both machines or whether client.pl only runs on PC1 and server.pl only runs on PC2.

      I would conceptually split up the "STAT" part separate from the "ADD" part. You can combine the server parts of both if the general format of an incoming message is the same.

      The easiest approach to combine the logic of the listeners and the senders in a single program is to launch for threads, two listener threads and two sender threads, or just two threads if you only need a listener on port 8000 and a sender to port 8010 (PC2) or a listener on port 8010 and a sender to port 8000 (PC1).

      The next step would be to look at AnyEvent or IO::Select to manage the writing to sockets and the reading from sockets. AnyEvent gives you callbacks for each socket when it's ready to write more data or when it's ready to read more data.

      Personally, I would go with the AnyEvent approach because that avoids race conditions.

        Hi Corion, thank you for your insight! Would it be possible to ask for a boilerplate of what you mentioned? I've done some basic work with IO::Socket::INET and what I had tried to do was along the lines of creating an INET socket with client and server using PeerAddr/PeerPort & LocalPort but was never able to accomplish the task. I had previously looked over AnyEvent and IO::Select but was unable to figure out where to start with the type of application I'd use them for. Thank you for any assistance!