⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch17_08.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 17.7. Identifying the Other End of a Socket (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen &amp; Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:44:32Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch17_01.htm"TITLE="17. Sockets"><LINKREL="prev"HREF="ch17_07.htm"TITLE="17.6. Using UNIX Domain Sockets"><LINKREL="next"HREF="ch17_09.htm"TITLE="17.8. Finding Your Own Name and Address"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch17_07.htm"TITLE="17.6. Using UNIX Domain Sockets"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 17.6. Using UNIX Domain Sockets"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch17_01.htm"TITLE="17. Sockets"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch17_09.htm"TITLE="17.8. Finding Your Own Name and Address"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 17.8. Finding Your Own Name and Address"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch17-26620">17.7. Identifying the Other End of a Socket</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch17-pgfId-922">Problem<ACLASS="indexterm"NAME="ch17-idx-1000004772-0"></A><ACLASS="indexterm"NAME="ch17-idx-1000004772-1"></A></A></H3><PCLASS="para">You have a socket and want to identify the machine at the other end.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch17-pgfId-928">Solution</A></H3><PCLASS="para">If you're only interested in the IP address of the remote machine, use:</P><PRECLASS="programlisting">use Socket;$other_end         = getpeername(SOCKET)    or die &quot;Couldn't identify other end: $!\n&quot;;($port, $iaddr)    = unpack_sockaddr_in($other_end);$ip_address        = inet_ntoa($iaddr);</PRE><PCLASS="para">If you want its actual host name, use:</P><PRECLASS="programlisting">use Socket;$other_end        = getpeername(SOCKET)    or die &quot;Couldn't identify other end: $!\n&quot;;($port, $iaddr)   = unpack_sockaddr_in($other_end);$actual_ip        = inet_ntoa($iaddr);$claimed_hostname = gethostbyaddr($iaddr, AF_INET);@name_lookup      = gethostbyname($claimed_hostname)    or die &quot;Could not look up $claimed_hostname : $!\n&quot;;@resolved_ips     = map { inet_ntoa($_) }    @name_lookup[ 4 .. $#ips_for_hostname ];</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch17-pgfId-970">Discussion</A></H3><PCLASS="para">For a long time, figuring out who connected to you was considered more straightforward than it really is. The <CODECLASS="literal">getpeername</CODE> function returns the IP address of the remote machine in a packed binary structure (or <CODECLASS="literal">undef</CODE> if an error occurred). To unpack it, use <CODECLASS="literal">inet_ntoa</CODE>. If you want the name of the remote end, call <CODECLASS="literal">gethostbyaddr</CODE> to look up the name of the machine in the DNS tables, right?</P><PCLASS="para">Not really. That's only half the solution. Because a name lookup goes to the name's owner's DNS server and a lookup of an IP addresses goes to the address's owner's DNS server, you have to contend with the possibility that the machine that connected to you is giving incorrect names. For instance, the machine <CODECLASS="literal">evil.crackers.org</CODE> could belong to malevolent cyberpirates who tell their DNS server that its IP address (<CODECLASS="literal">1.2.3.4</CODE>) should be identified as <CODECLASS="literal">trusted.dod.gov</CODE>. If your program trusts <CODECLASS="literal">trusted.dod.gov</CODE>, a connection from <CODECLASS="literal">evil.crackers.org</CODE> will cause <CODECLASS="literal">getpeername</CODE> to return the right IP address (<CODECLASS="literal">1.2.3.4</CODE>), but <CODECLASS="literal">gethostbyaddr</CODE> will return the duplicitous name.</P><PCLASS="para">To avoid this problem, we take the (possibly deceitful) name returned by <CODECLASS="literal">get-hostbyaddr</CODE><ACLASS="indexterm"NAME="ch17-idx-1000004778-0"></A><ACLASS="indexterm"NAME="ch17-idx-1000004778-1"></A> and look it up again with <CODECLASS="literal">gethostbyname</CODE>. In the case of <CODECLASS="literal">evil.crackers.org</CODE>, the lookup of <CODECLASS="literal">trusted.dod.gov</CODE> will be done through <CODECLASS="literal">dod.gov</CODE>'s DNS servers, and will return the real IP address(es) for <CODECLASS="literal">trusted.dod.gov</CODE>. Because many machines have more than one IP address (multihomed web servers are the obvious example), we can't use the simplified form of <CODECLASS="literal">gethostbyname</CODE>:</P><PRECLASS="programlisting">$packed_ip  = gethostbyname($name) or die &quot;Couldn't look up $name : $!\n&quot;;$ip_address = inet_ntoa($packed_ip);</PRE><PCLASS="para">So far we've assumed we're dealing with an Internet domain application. You can also call <CODECLASS="literal">getpeername</CODE> on a Unix domain socket. If the other end called <CODECLASS="literal">bind</CODE>, you'll get the filename they bound to. If the other end <EMCLASS="emphasis">didn't</EM> call <CODECLASS="literal">bind</CODE>, however, <CODECLASS="literal">getpeername</CODE> may return an empty string (unpacked), a packed string with oddball garbage in it, or <CODECLASS="literal">undef</CODE> to indicate an error, or your computer may reboot. (These possibilities are listed in descending order of probability and desirability.) This is what we in the computer business call "undefined behavior."<ACLASS="indexterm"NAME="ch17-idx-1000004774-0"></A><ACLASS="indexterm"NAME="ch17-idx-1000004774-1"></A></P><PCLASS="para">Even this level of paranoia and mistrust isn't enough. It's still possible for people to fake out DNS servers they don't directly control, so don't use hostnames for identification or authentication. True paranoiacs and misanthropes use cryptographically-secure methods.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch17-pgfId-1000005818">See Also</A></H3><PCLASS="para">The <ACLASS="olink"HREF="../prog/ch03_047.htm">&#13;<CODECLASS="literal">gethostbyaddr</CODE></A>, <ACLASS="olink"HREF="../prog/ch03_048.htm">&#13;<CODECLASS="literal">gethostbyname</CODE></A>, and <ACLASS="olink"HREF="../prog/ch03_054.htm">&#13;<CODECLASS="literal">getpeername</CODE></A> in <ACLASS="olink"HREF="../prog/ch03_01.htm">Chapter 3</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A> and in <ICLASS="filename">perlfunc </I>(1); the <CODECLASS="literal">inet_ntoa</CODE> in the standard Socket module; the documentation for the standard IO::Socket and Net::hostnet modules</P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch17_07.htm"TITLE="17.6. Using UNIX Domain Sockets"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 17.6. Using UNIX Domain Sockets"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch17_09.htm"TITLE="17.8. Finding Your Own Name and Address"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 17.8. Finding Your Own Name and Address"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">17.6. Using UNIX Domain Sockets</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">17.8. Finding Your Own Name and Address</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright &copy; 2002</a> O'Reilly &amp; Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -