<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post//</link>
<title><![CDATA[linux shell 脚本实现tcp/upd协议通讯（重定向应用）]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[Unix/LinuxC技术]]></category>
<pubDate>Sun, 26 Apr 2015 10:02:06 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	背景：有时像硬件测试，比如SIM900a，如果你有一台公网ip服务器，想开一个tcp上的ip端口，在Windows下有tcp/ip的调试助手的界面软件，而linux下没有这样的玩意，怎么办呢？shell有这个功能，好像nc也有类似的模拟client去连接服务器的功能，咱就先找个shell的，Linux 下有兄弟好像写了一个debian下的的deb包：http://blog.chinaunix.net/uid-21977056-id-4310527.html 如下。<br/>bash socket 编程 ：<br/>在bash环境中,你可以打开一个socket,并通过它发送数据. 并不需要安装curl或者lynx等程序.<br/><br/>通过两个特殊的设备文件, 可以打开网络socket<br/><br/>/dev/tcp/host/port<br/><br/>如果 host是一个有效的主机名或者IP地址, 端口号是一个整数或者常见的服务名(如dns, http), 那么bash将打开一个TCP连接 <br/>/dev/udp/host/port<br/><br/>打开到host:port的UDP连接<br/><br/>(echo &gt;/dev/tcp/localhost/80) &amp;&gt;/dev/null &amp;&amp; echo “TCP port 80 open” &#124;&#124; echo “TCP port 80 close”<br/>/dev/[tcp&#124;upd]/host/port 只要读取或者写入这个文件，相当于系统会尝试连接:host 这台机器，对应port端口。如果主机以及端口存在，就建立一个socket 连接。将在，/proc/self/fd目录下面，有对应的文件出现。<br/>用来判断本机的80端口是否打开<br/><br/>另外, 一段crontab脚本<br/><br/>!/bin/bash<br/>exec 8&lt;&gt;/dev/tcp/zhiwei.li/80<br/><br/>if [ $? -eq 0 ] ; then<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;printf &quot;GET /status HTTP/1.0rn&quot; &gt;&amp;8<br/>&nbsp;&nbsp;&nbsp;&nbsp;printf &quot;Host: zhiwei.lirn&quot; &gt;&amp;8<br/>&nbsp;&nbsp;&nbsp;&nbsp;printf &quot;User-Agent: Mozilla/5.0rn&quot; &gt;&amp;8<br/>&nbsp;&nbsp;&nbsp;&nbsp;printf &quot;rn&quot; &gt;&amp;8<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;while read -u 8 -r -t 2 block;<br/>&nbsp;&nbsp;&nbsp;&nbsp;do<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo $block<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;$(date) - web server is running.&quot;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while read -u 8 line ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo $line<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;done<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exec 8&amp;-<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit<br/>&nbsp;&nbsp;&nbsp;&nbsp;done<br/>fi<br/><br/>echo “need reboot” <br/>…. <br/>来自：http://my.oschina.net/panzhc/blog/182843#OSC_h1_1<br/>参考资料： <br/>http://xpt.sourceforge.net/techdocs/nix/shell/gsh05-ShBash/ar01s28.html <br/>http://www.cyberciti.biz/tips/spice-up-your-unix-linux-shell-scripts.html<br/>————————————————————————————————————————————<br/>一）如果出于效率的话还是选择工具的好shell不怎么合适做这个^_^，但作测试足够了：<br/>直接在交互shell下<br/>exec 3&lt;/dev/tcp/localhost/80<br/>exec 3&lt;/dev/tcp/localhost/25<br/>lsof -p $$<br/>我开了httpd和sendmail服务，因此80和25端口有响应。<br/>可以看到当前shell只打开了25这个端口。<br/><br/>二）如何查看这个shell是否真正打开了这个80端口？<br/>一、安装nmap<br/>yum install nmap #输入y安装<br/>二、使用nmap<br/>nmap localhost #查看主机当前开放的端口<br/>nmap -p 1024-65535 localhost#查看主机端口（1024-65535）中开放的端口<br/>nmap -PS 192.168.21.163 #探测目标主机开放的端口<br/>nmap -PS22,80,3306 192.168.21.163 #探测所列出的目标主机端口<br/>nmap -O 192.168.21.163 #探测目标主机操作系统类型<br/>nmap -A 192.168.21.163 #探测目标主机操作系统类型<br/>nmap --help #更多nmap参数请查询帮助信息<br/>三、关闭或者打开主机端口<br/>1、nmap localhost #查看主机当前开放端口<br/>2、ntsysv #打开系统服务器管理器（需要先安装yum install ntsysv），选择要关闭或者打开的服务<br/>摘自：http://www.dedecms.com/knowledge/servers/linux-bsd/2012/0819/8442.html<br/>nmap localhost&nbsp;&nbsp;<br/><br/>Starting Nmap 5.51 ( http://nmap.org ) at 2015-04-26 18:07 CST<br/>Nmap scan report for localhost (127.0.0.1)<br/>Host is up (0.000026s latency).<br/>Other addresses for localhost (not scanned): 127.0.0.1<br/>Not shown: 992 closed ports<br/>PORT&nbsp;&nbsp;&nbsp;&nbsp; STATE SERVICE<br/>22/tcp&nbsp;&nbsp; open&nbsp;&nbsp;ssh<br/>25/tcp&nbsp;&nbsp; open&nbsp;&nbsp;smtp<br/>80/tcp&nbsp;&nbsp; open&nbsp;&nbsp;http<br/>111/tcp&nbsp;&nbsp;open&nbsp;&nbsp;rpcbind<br/>443/tcp&nbsp;&nbsp;open&nbsp;&nbsp;https<br/>5901/tcp open&nbsp;&nbsp;vnc-1<br/>6001/tcp open&nbsp;&nbsp;X11:1<br/>8080/tcp open&nbsp;&nbsp;http-proxy<br/><br/>三）测试：用telnet就行了。<br/>——————————————————————————————————————————————————————————<br/>http://www.csdn.net/article/2012-02-28/312483<br/>时间 2014-03-17 22:04:04&nbsp;&nbsp;向东博客<br/>原文&nbsp;&nbsp;http://jackxiang.com/post/7098/<br/><br/>前几天发了重定向以及管道相关使用方法，今天这里发些很有趣的例子。通过重定向实现基于tcp/udp协议的软件通讯。<br/>linux 设备里面有个比较特殊的文件:<br/><br/>/dev/[tcp&#124;upd]/host/port 只要读取或者写入这个文件，相当于系统会尝试连接:host 这台机器，对应port端口。如果主机以及端口存在，就建立一个socket 连接。将在，/proc/self/fd目录下面，有对应的文件出现。<br/><br/>一、测试下：/dev/tcp/host/post文件<br/>[chengmo@centos5&nbsp;&nbsp;shell]$ cat&lt;/dev/tcp/127.0.0.1/22<br/>SSH-2.0-OpenSSH_5.1<br/>#我的机器shell端口是：22<br/>#实际:/dev/tcp根本没有这个目录，这是属于特殊设备<br/>[chengmo@centos5&nbsp;&nbsp;shell]$ cat&lt;/dev/tcp/127.0.0.1/223<br/>-bash: connect: 拒绝连接<br/>-bash: /dev/tcp/127.0.0.1/223: 拒绝连接<br/>#223接口不存在,打开失败<br/> <br/>[chengmo@centos5&nbsp;&nbsp;shell]$ exec 8&lt;&gt;/dev/tcp/127.0.0.1/22<br/>[chengmo@centos5&nbsp;&nbsp;shell]$ ls -l /proc/self/fd/<br/>总计 0<br/>lrwx------ 1 chengmo chengmo 64 10-21 23:05 0 -&gt; /dev/pts/0<br/>lrwx------ 1 chengmo chengmo 64 10-21 23:05 1 -&gt; /dev/pts/0<br/>lrwx------ 1 chengmo chengmo 64 10-21 23:05 2 -&gt; /dev/pts/0<br/>lr-x------ 1 chengmo chengmo 64 10-21 23:05 3 -&gt; /proc/22185/fd<br/>lrwx------ 1 chengmo chengmo 64 10-21 23:05 8 -&gt; socket:[15067661]<br/> <br/>#文件描述符8，已经打开一个socket通讯通道，这个是一个可以读写socket通道,因为用：&quot;&lt;&gt;&quot;打开<br/>[chengmo@centos5&nbsp;&nbsp;shell]$ exec 8&gt;&amp;-<br/>#关闭通道<br/>[chengmo@centos5&nbsp;&nbsp;shell]$ ls -l /proc/self/fd/<br/>总计 0<br/>lrwx------ 1 chengmo chengmo 64 10-21 23:08 0 -&gt; /dev/pts/0<br/>lrwx------ 1 chengmo chengmo 64 10-21 23:08 1 -&gt; /dev/pts/0<br/>lrwx------ 1 chengmo chengmo 64 10-21 23:08 2 -&gt; /dev/pts/0<br/>lr-x------ 1 chengmo chengmo 64 10-21 23:08 3 -&gt; /proc/22234/fd<br/> <br/><br/>从时间服务器读取时间：<br/><br/>[chengmo@centos5 html]$ cat&lt;/dev/tcp/time-b.nist.gov/13<br/><br/>55491 10-10-22 11:33:49 17 0 0 596.3 UTC(NIST) *<br/><br/>上面这条语句使用重定向输入语句就可以了。<br/><br/> <br/><br/>二、通过重定向读取远程web服务器头信息<br/>#!/bin/sh <br/>#testhttphead.sh<br/>#实现通过主机名，端口读取web 服务器header信息<br/>#copyright chengmo,qq:8292669<br/> <br/>if(($#&lt;2));then<br/>&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;usage:$0 host port&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;exit 1;<br/>fi<br/>#如果参数缺失，退出程序，返回状态1<br/> <br/>exec 6&lt;&gt;/dev/tcp/$1/$2 2&gt;/dev/null;<br/>#打开host的port 可读写的socket连接，与文件描述符6连接<br/> <br/>if(($?!=0));then<br/>&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;open $1 $2 error!&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;exit 1;<br/>fi<br/>#如果打开失败，$?返回不为0，终止程序<br/> <br/>echo -e &quot;HEAD / HTTP/1.1&#92;n&#92;n&#92;n&#92;n&#92;n&quot;&gt;&amp;6; <br/>#将HEAD 信息，发送给socket连接<br/> <br/>cat&lt;&amp;6; <br/>#从socket读取返回信息，显示为标准输出<br/> <br/>exec 6&lt;&amp;-;<br/>exec 6&gt;&amp;-; <br/>#关闭socket的输入，输出<br/> <br/>exit 0;<br/> <br/><br/>脚本建立后：存为testhttphead.sh<br/><br/>运行结果：<br/>[chengmo@centos5 ~/shell]$ sh testhttphead.sh www.baidu.com 80<br/>HTTP/1.1 200 OK<br/>Date: Thu, 21 Oct 2010 15:17:23 GMT<br/>Server: BWS/1.0<br/>Content-Length: 6218<br/>Content-Type: text/html;charset=gb2312<br/>Cache-Control: private<br/>Expires: Thu, 21 Oct 2010 15:17:23 GMT<br/>Set-Cookie: BAIDUID=1C40B2F8C676180FD887379A6E286DC1:FG=1; expires=Thu, 21-Oct-40 15:17:23 GMT; path=/; domain=.baidu.com<br/>P3P: CP=&quot; OTI DSP COR IVA OUR IND COM &quot;<br/>Connection: Keep-Alive<br/> <br/>[chengmo@centos5 ~/shell]$ sh testhttphead.sh 127.0.0.1 8080<br/>open 127.0.0.1 8080 error!<br/>突然有个奇怪想法：<br/>我们在windows时代就通过telnet 可以实现tcp/upd协议通讯，那么如果用传统方法怎么实现呢？<br/>[chengmo@centos5 ~/shell]$ echo -e &quot;HEAD / HTTP/1.1&#92;n&#92;n&#92;n&#92;n&#92;n&quot;&#124;telnet www.baidu.com 80 <br/>Trying 220.181.6.175...<br/>Connected to www.baidu.com.<br/>Escape character is &#039;^]&#039;.<br/>Connection closed by foreign host.<br/> <br/>#直接给发送，失败<br/>[chengmo@centos5 ~/shell]$ (telnet www.baidu.com 80)&lt;&lt;EOF<br/>HEAD / HTTP/1.1<br/> <br/>&nbsp;&nbsp;<br/>EOF<br/>Trying 220.181.6.175...<br/>Connected to www.baidu.com.<br/>Escape character is &#039;^]&#039;.<br/>Connection closed by foreign host.<br/>#重定向输入，还是失败？<br/>找到正确方法：<br/>[chengmo@centos5 shell]$ (echo -e &quot;HEAD / HTTP/1.1&#92;n&#92;n&#92;n&#92;n&#92;n&quot;;sleep 2)&#124;telnet www.baidu.com 80 <br/>Trying 220.181.6.175...<br/>Connected to www.baidu.com.<br/>Escape character is &#039;^]&#039;.<br/>HTTP/1.1 200 OK<br/>Date: Thu, 21 Oct 2010 15:51:58 GMT<br/>Server: BWS/1.0<br/>Content-Length: 6218<br/>Content-Type: text/html;charset=gb2312<br/>Cache-Control: private<br/>Expires: Thu, 21 Oct 2010 15:51:58 GMT<br/>Set-Cookie: BAIDUID=0B6A01ACECD5353E4247E088A8CB345A:FG=1; expires=Thu, 21-Oct-40 15:51:58 GMT; path=/; domain=.baidu.com<br/>P3P: CP=&quot; OTI DSP COR IVA OUR IND COM &quot;<br/>Connection: Keep-Alive<br/>#成功了！加入sleep 居然可以了，sleep 改成1秒也可以<br/> <br/><br/>是不是由于sleep后，echo会推出2秒发给通道：telnet呢？推论可以从这2个方面推翻：<br/><br/>一个方面：通过()括的数据是一对命令，会作为一个子命令执行，一起执行完程序结束。每个命令echo语句，就直接发送到屏幕（也就是标准输出），只要有标准输出了，就会通过通道马上传个：telnet ，如果接下来命令还有输出，会注意传给telnet ，直到()内所有命令执行完，与通道连接就断开了。<br/><br/> <br/><br/>再一个方面：如果说是起到推迟发送的话，什么时候有数据过来，发给telnet，什么时候telnet命令启动。跟你推迟一点还是早一点发送过来。没有关系。<br/><br/> <br/><br/>这种类型命令，看出sleep，其实就是保持通道跟telnet 连接2秒钟。 通道连接着了，telnet终端输入也还在，因此可以保持从baidu服务器获得数据。<br/><br/>所以,延迟多久，还是跟服务器处理速度有关系。<br/><br/> <br/><br/>如果通过echo 向telnet发送数据，保持通道联通，使用sleep是个很好方法。<br/><br/>通过重定向给telnet输入参数这种方法，我还想不到怎么样实现延迟输入。有知道朋友，可以指点指点.<br/><br/>区别：<br/><br/>telnet与echo 实现 http访问，与通过打开读写socket是不一样的，打开socket通道，是可以进行交换处理的。传入命令，活动结果，再传入命令，再获得结果。telnet通过echo 就不能这样处理了。<br/><br/> <br/><br/> <br/><br/> <br/><br/>三、通过shell脚本重定向实现监控memcache状态<br/><br/>实例：<br/>#!/bin/sh<br/> <br/>#通过传入ip 以及端口，发送指令获得返回数据<br/>#copyright chengmo qq:8292669<br/> <br/>#函数往往放到最上面<br/>function sendmsg()<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;msg=$1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;&nbsp;&quot;$1&quot;&gt;&amp;8;<br/>&nbsp;&nbsp;&nbsp;&nbsp;getout;<br/>&#125;<br/>#向socket通道发送指令，并且调用获得返回参数<br/> <br/>function getout()<br/>&#123;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;#read 命令 -u 从打开文件描述符 8 读取数据，-d读取数据忽略掉:&#92;r换行符 <br/>&nbsp;&nbsp;&nbsp;&nbsp;while read -u 8 -d $&#039;&#92;r&#039; name; <br/>&nbsp;&nbsp;&nbsp;&nbsp;do <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if [ &quot;$&#123;name&#125;&quot; == &quot;END&quot;&nbsp;&nbsp;-o &quot;$&#123;name&#125;&quot; == &quot;ERROR&quot; ];then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo $name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;done<br/>&#125;<br/>#由于：memcached每次通讯完毕，会返回：END或者ERROR(出错），通过判断是否是&quot;END&quot;觉得读取是不是结束，否则循环不会停止<br/> <br/>if [ $# -lt 2 ];then<br/>&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;usage:$0 host port [command]&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;exit 1;<br/>fi;<br/> <br/>[[ $# -gt 2 ]]&amp;&amp;command=$3;<br/> <br/>#设置默认值 如果command为定义则为：stats<br/>command=&quot;$&#123;command=stats&#125;&quot;;<br/>host=&quot;$1&quot;;<br/>port=&quot;$2&quot;;<br/> <br/> <br/> <br/>exec 8&lt;&gt;/dev/tcp/$&#123;host&#125;/$&#123;port&#125;;<br/>#打开通向通道是8<br/> <br/>if [ &quot;$?&quot; != &quot;0&quot; ];then<br/>&nbsp;&nbsp;&nbsp;&nbsp;echo &quot;open $host&nbsp;&nbsp;$port fail!&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;exit 1;<br/>fi<br/> <br/>sendmsg &quot;$command&quot;;<br/>#发送指定命令<br/> <br/> <br/>sendmsg &quot;quit&quot;;<br/>#发送退出通向命令<br/> <br/> <br/>exec 8&lt;&amp;-;<br/>exec 8&gt;&amp;-;<br/>#关闭socket通道<br/> <br/>exit 0;<br/> <br/><br/>这是通过重定向，实现socket通讯中，发送然后获取返回的例子。其实，上面代码看似一次只能发送一段。时间上。我们可以反复调用：sendmsg ，捕捉输出数据。实现连续的，读与写操作。<br/><br/>实例截图：<br/><br/> <br/><br/>其它实现方法：<br/><br/>其实通过：telnet也可以实现的。<br/><br/>[chengmo@centos5 shell]$ (echo &quot;stats&quot;;sleep 2)&#124;telnet 127.0.0.1 11211<br/><br/>通过nc命令实现：<br/><br/>[chengmo@centos5 shell]$ (echo &quot;stats&quot;)&#124;nc 127.0.0.1 11211<br/><br/>不需要加延迟，直接打开通道<br/><br/>第二个程序里面，看到shell完全可以处理交互设计了。如果按照这样，登陆ftp,pop3,stmp都可以类似实现。这些，我们通过shell socket类似程序实现，应该不困难，只是捕捉如发送解析的问题了。<br/><br/>来自：http://www.cnblogs.com/chengmo/archive/2010/10/22/1858302.html<br/><br/>http://blog.chinaunix.net/uid-21454189-id-442258.html
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] linux shell 脚本实现tcp/upd协议通讯（重定向应用）]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>