How To Make Filehandle Global To Package?

Ask a Question related to PERL Miscellaneous, Design and Development.

  1. #1

    Default How To Make Filehandle Global To Package?

    All:

    I have a main program that calls methods in a module/package. A method call
    to the subroutine below opens a socket which I want to make global to the
    package (eg. other subroutines will read and write from/to the socket).
    Currently, the socket is considered closed by other methods that attempt to
    use it.

    I've tried to get the answer from the following sources:

    - Programming Perl
    - perlopentut
    - various perldoc requests
    - perlfaq5 - How do I pass filehandles between subroutines?

    There is plenty of information but I still can't quite figure it out.

    Thanks for your understanding and aid.

    Moose


    #SUBROUTINE


    sub open_UDP_socket {

    my $local_ipaddr;
    my $portaddr;
    my $local_port = 7082;

    print "Opening socket...\n";

    $local_ipaddr = gethostbyname(hostname());
    $portaddr = sockaddr_in($local_port, INADDR_ANY);

    socket(SOCKHANDLE, PF_INET, SOCK_DGRAM, getprotobyname("udp"))
    || die "socket: $!";
    setsockopt(SOCKHANDLE, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) or
    die "setsockopt: $!";

    bind(SOCKHANDLE, $portaddr) || die "bind: $!";

    } # end sub open_UDP_socket

    mooseshoes Guest

  2. Similar Questions and Discussions

    1. Newbie Q: how to make a cpan package
      "Ignoramus23186" <ignoramus23186@NOSPAM.23186.invalid> wrote in message news:K3PQe.110824$f24.30223@fe18.usenetserver.com... perldoc -q "create a...
    2. No way to select all fields and make a global change?
      Hi -- Using Acrobat 6 with rudimentary skills (or else Acrobat is rudimentary). Have created a form and would now like to change all of the...
    3. [PHP] URGENT: how to make a global "server temporarily down" page?
      David Robley <mailto:robleyd@ozemail.com.au> on Friday, September 05, 2003 5:59 AM said: Yeah, like a rewrite rule. RewriteRule ^*$ down.html
    4. URGENT: how to make a global "server temporarily down" page?
      Typing "Apache custom 404" and clicking on "I feel lucky" would get you to this information: Apache Add the following directive to your...
    5. how to make a global scope array
      <20030725224852.1123.qmail@pb1.pair.com> Jack Lee: global $a;
  3. #2

    Default Re: How To Make Filehandle Global To Package?

    >>>>> "m" == mooseshoes <mooseshoes@gmx.net> writes:

    m> I have a main program that calls methods in a module/package. A
    m> method call to the subroutine below opens a socket which I want to
    m> make global to the package (eg. other subroutines will read and
    m> write from/to the socket). Currently, the socket is considered
    m> closed by other methods that attempt to use it.

    so just store the handle in a package var. or even better if the class code
    is all in one file, store the handle in a file scoped lexical.

    m> I've tried to get the answer from the following sources:

    m> - Programming Perl
    m> - perlopentut

    that would have nothing on where to store handles.

    m> - various perldoc requests

    which ones?

    m> - perlfaq5 - How do I pass filehandles between subroutines?

    did you learn that handles can be stored anywhere?

    m> sub open_UDP_socket {

    m> my $local_ipaddr;
    m> my $portaddr;
    m> my $local_port = 7082;

    m> print "Opening socket...\n";

    m> $local_ipaddr = gethostbyname(hostname());
    m> $portaddr = sockaddr_in($local_port, INADDR_ANY);

    m> socket(SOCKHANDLE, PF_INET, SOCK_DGRAM, getprotobyname("udp"))
    m> || die "socket: $!";
    m> setsockopt(SOCKHANDLE, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) or
    m> die "setsockopt: $!";

    m> bind(SOCKHANDLE, $portaddr) || die "bind: $!";

    bah, use IO::Socket and remove all that mess.

    you are using a named handle. that IS package scoped so any code
    in the package could access it by that name. nothing else needs to be
    done but that is a poor solution. the IO::Socket module will return a
    handle to you that you can store anywhere. a file lexical is best (given
    what you said so far). if this module were OO i would store the handle
    in the object (a very common place for it).

    uri

    --
    Uri Guttman ------ [email]uri@stemsystems.com[/email] -------- [url]http://www.stemsystems.com[/url]
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- [url]http://jobs.perl.org[/url]
    Damian Conway Class in Boston - Sept 2003 -- [url]http://www.stemsystems.com/class[/url]
    Uri Guttman Guest

  4. #3

    Default Re: How To Make Filehandle Global To Package?

    Hey Uri. Thanks for the responses.

    <snip>
    > so just store the handle in a package var. or even better if the class
    > code is all in one file, store the handle in a file scoped lexical.
    >
    <<< I did try declaring "our $socket_handle" for the package and using that
    instead of the named handle but ran into the same problem. If it is that
    simple, then I'm likely doing something else wrong such that another
    subroutine in the same package thinks the filehandle is closed.

    <snip>
    > did you learn that handles can be stored anywhere?
    <<< Yep.


    <snip>
    > bah, use IO::Socket and remove all that mess.
    <<< It was originally done with IO::Socket. I ran into trouble with it
    because socket sends are done independent of socket receives (eg. can't
    take advantage of the stored peer address) and for multiple clients. The
    portaddr needs to get set outside the socket declaration and for some
    reason IO::Socket gives me "can't find peer address" errors during sends
    even when I seemingly set the portaddr correctly and include it in send
    command.

    <snip>
    > you are using a named handle. that IS package scoped so any code
    > in the package could access it by that name. nothing else needs to be
    > done but that is a poor solution. the IO::Socket module will return a
    > handle to you that you can store anywhere. a file lexical is best (given
    > what you said so far). if this module were OO i would store the handle
    > in the object (a very common place for it).
    <<< I haven't done much with OO but can see how much cleaner it is. I'll
    try to give IO::Socket another try and store the handle.

    Thanks again.

    Cheers,

    Moose

    mooseshoes Guest

  5. #4

    Default Re: How To Make Filehandle Global To Package?

    Uri,

    I dropped "our $socket_handle" back in at the top and now it's working.

    Such is life.


    Peace,

    Moose
    mooseshoes Guest

  6. #5

    Default Re: How To Make Filehandle Global To Package?

    >>>>> "m" == mooseshoes <mooseshoes@gmx.net> writes:
    >> so just store the handle in a package var. or even better if the class
    >> code is all in one file, store the handle in a file scoped lexical.
    >>
    m> <<< I did try declaring "our $socket_handle" for the package and using that
    m> instead of the named handle but ran into the same problem. If it is that
    m> simple, then I'm likely doing something else wrong such that another
    m> subroutine in the same package thinks the filehandle is closed.

    that isn't what i said. if you read perlopentut carefully you will see
    that a named filehandle (FH) is not the same as using a varaible like
    $fh. in recent perls, a variable with undef will get autovivified to
    have a unique handle when it is used in open (and i would guess socket,
    pipe, and other handle creators). so what version of perl are you
    running?

    and you should show the code that failed for you when doing a file
    lexical. and our does not create file lexicals. use my outside any sub
    to get that.
    >> bah, use IO::Socket and remove all that mess.
    m> <<< It was originally done with IO::Socket. I ran into trouble with it
    m> because socket sends are done independent of socket receives (eg. can't
    m> take advantage of the stored peer address) and for multiple clients. The
    m> portaddr needs to get set outside the socket declaration and for some
    m> reason IO::Socket gives me "can't find peer address" errors during sends
    m> even when I seemingly set the portaddr correctly and include it in send
    m> command.

    huh?? what does send and recv being independent have to do with
    anything? you can set the port address with send via the TO
    argument. peer addresses are meaningful only when receiving UDP
    messages. so why are you trying to get the peer address after you sent
    something and you know the address you sent it to?

    m> <<< I haven't done much with OO but can see how much cleaner it is. I'll
    m> try to give IO::Socket another try and store the handle.

    beyond storing the handle, i am not sure what you are doing with this
    UDP socket. explain the larger picture and i bet there is a much simpler
    solution and design. this need of yours to share the handle for peer
    address stuff makes me suspect an XY problem. you found a direction to
    go even if it isn't the best way to solve the real problem.

    uri

    --
    Uri Guttman ------ [email]uri@stemsystems.com[/email] -------- [url]http://www.stemsystems.com[/url]
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- [url]http://jobs.perl.org[/url]
    Damian Conway Class in Boston - Sept 2003 -- [url]http://www.stemsystems.com/class[/url]
    Uri Guttman Guest

  7. #6

    Default Re: How To Make Filehandle Global To Package?


    <snip>

    > that isn't what i said. if you read perlopentut carefully you will see
    > that a named filehandle (FH) is not the same as using a varaible like
    > $fh. in recent perls, a variable with undef will get autovivified to
    > have a unique handle when it is used in open (and i would guess socket,
    > pipe, and other handle creators). so what version of perl are you
    > running?
    <<< using 5.8. Are you saying that using a variable instead of a named
    filehandle is more likely to break? I'm having success now by using a
    variable that is global to the package. Is it better to change it to a
    name filehandle?

    <snip>
    > and you should show the code that failed for you when doing a file
    > lexical. and our does not create file lexicals. use my outside any sub
    > to get that.

    <<< I traced it back to a thread problem. I had opened the socket on a
    thread mistakingly and the send call couldn't find the socket so it assumed
    it was closed. Yes, the plot thickens. Read on.


    <snip>
    > huh?? what does send and recv being independent have to do with
    > anything? you can set the port address with send via the TO
    > argument. peer addresses are meaningful only when receiving UDP
    > messages. so why are you trying to get the peer address after you sent
    > something and you know the address you sent it to?
    <<< I don't remember seeing any "TO" argument in my documentation. I did
    use the form $sock->send($msg, $portaddr), however, and each time would get
    a "can't find peer address" error or something to that affect. Not sure
    why.

    <snip>
    > beyond storing the handle, i am not sure what you are doing with this
    > UDP socket. explain the larger picture and i bet there is a much simpler
    > solution and design. this need of yours to share the handle for peer
    > address stuff makes me suspect an XY problem. you found a direction to
    > go even if it isn't the best way to solve the real problem.
    <<<Uri, you're OK. I like your energy and your knowledge is likely to help
    more than just me in this forum. UDP sockets are used in two ways in the
    program. There are Stayalive sockets (read) and a Message socket (send).
    The Stayalives support up to X clients that periodically send messages to
    keep a "logged on" status and update the send_to_port data (routers
    constantly change this data). The Message socket sends a message to a
    client when a message becomes available from the main program. The IP
    address and port number are looked up prior to the send. Stayalive and
    Message sockets live on ithreads. There is also a TCP login socket which
    is also threaded but not relevant to this discussion. There are a number
    of ways to do all this, but using UDP in this manner is the least resource
    intensive even when compared to HTTP. Enough said, I suppose. If you want
    more detail, let me know.

    Moose

    mooseshoes Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139