in reply to IO:Socket::NET problem & Counter-Strike

I only took a quick look but I think this is the problem...

1) It looks like your splitter creates a new socket each time it wants to forward a packet. This is extremely wasteful.

2) The splitter doesn't specify what local port to send from so each time you create this new socket it will get a new local port number.

3) Your check is against the sender's (splitter's) source port so, yes, that port number will be constantly changing and you'll get the error you describe.

So the fix is to move the new() method call outside of the loop in your splitter.

Just in case there is some deeper confusion involved in this mistake Also, a bit of a tutorial on some much-misunderstood aspect of TCP/IP is probably in order...

Every UDP packet (or TCP connect) has four address elements associated with it: Source IP address, source port number, destination IP address, and destination port number. When talking about a socket we replace "source" and "destination" with "local" and "remote".

A server usually specifies its local port number and nothing else. The local IP address is determined by the address the client uses to contact the server (having a server specify the local IP address is about the most common TCP/IP programming mistake there is). A client usually specifies the the remote IP address and remote port number and lets the operating system fill in appropriate local IP address (depends on the network interface that will be used to reach the server, determined from the server's IP address) and local port number (pretty much a random port number that is currently not in use).

So you don't want to create a new UDP socket for each packet that you send out. In fact, you can just use one socket for all three purposes in the splitter: receiving packets, sending copies to the first destination, and sending copies to the second destination (this wouldn't work for TCP since each socket has to be connected to a single desination). Just specify the destination address when you send each packet out.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: (tye)Re: IO:Socket::NET problem & Counter-Strike
by Myron DaChump (Initiate) on Mar 31, 2001 at 09:57 UTC
    So If I understand you correctly....I should change the code from this....

    while ($socket->recv(my $in, 1024) ) { my $sock = IO::Socket::INET->new( Proto => 'udp', PeerAddr =>'127.0.0.1:50000'); print $sock $in; }

    To this....

    my $sock = IO::Socket::INET->new( Proto => 'udp', LocalAddr =>'127.0.0.1:50000'); while ($socket->recv(my $in, 1024) ) { print $sock $in; }

    But do I need to specify the PeerAddr as well in the new statement? Also it would appear it won't reuse the socket, after one iteration, it says cannot write to socket.

    I admit I am not too smart and I looked at the Module docs, but the examples there don't specify a Peer and Local in the same command, am I able to?

    Thanks again Tye, I appreciate you taking the time to help me!

    -Myron DaChump

      Well, I don't see how it could write to the socket the first time since you don't give a destination address/port. Also, I strongly discourage specifying a local IP address and I don't recommend specifying a local port number. Certainly if you specify a local port number then you should be checking whether the new() fails!

              - tye (but my friends call me "Tye")
        Okay, then I am confused. I am not so sharp, so give me a leg up here. Would you mind actually composing an example socket for me?

        You are of course right about the NEW statment, moving the creation to outside of the loop does run, but when I start the other script to listen on port 50000 it says that the socket is already in use. I am lost boss.

        -Myron DaChump

Re: (tye)Re: IO:Socket::NET problem & Counter-Strike
by Myron DaChump (Initiate) on Mar 31, 2001 at 10:24 UTC
    WOOT! Finally figured it out! Thanks for your help!

    -Myron DaChump