Mar25

Linux select函数学习笔记

Author: leeon  Click: 7168   Comments: 0 Category: Linux C/C++编程  Tag: select,io,fd_set

转载了一个比较容易理解select函数作用的解释:

理解select模型的关键在于理解fd_set,为说明方便,取fd_set长度为1字节,fd_set中的每一bit可以对应一个文件描述符fd。则1字节长的fd_set最大可以对应8个fd。
(1)执行fd_set set; FD_ZERO(&set);则set用位表示是0000,0000。
(2)若fd=5,执行FD_SET(fd,&set);后set变为0001,0000(第5位置为1)
(3)若再加入fd=2,fd=1,则set变为0001,0011
(4)执行select(6,&set,0,0,0)阻塞等待
(5)若fd=1,fd=2上都发生可读事件,则select返回,此时set变为0000,0011。注意:没有事件发生的fd=5被清空。

注意第五条中的fd=5被清空,说明只要是不活跃的文件描述符都会在select的阻塞被结束后从原有的文件描述集合fd_set中被去除。因此在socket使用select的场景下,是可以在while轮询中使用FD_ISSET宏来不断监听服务器端生成的socket文件描述符是否活跃。

Mar20

IE Firefox 在进行某些跳转时请求头中不会附加 Referer 字段信息

Author: w3help.org  Click: 17457   Comments: 2 Category: 网络  Tag: refer,http

标准参考

根据 HTTP1.1 规范中的描述,请求头中的 Referer 字段允许用户端为服务端指定得到的请求 URI 的资源地址 (URI),允许服务端生成资源的反向链接列表,同时也允许追踪维护过时的或者是拼写错误的链接。若一个请求 URI 获得自一个没有自身 URI 的源,则该请求 URI 的 Referer 字段不得被发送,如来自用户键盘的输入。

  Referer = "Referer" ":" ( absoluteURI | relativeURI )

如:Referer: http://www.w3.org/hypertext/DataSources/Overview.html

关于 Referer 的更多信息,请参考 Hypertext Transfer Protocol -- HTTP/1.1 规范 14.36 Referer 中的内容。

问题描述

IE6 IE7 IE8 始终不在使用 META 元素控制跳转时附加 Referer 字段到请求头中。在普通页面中,当脚本调用 location 对象进行跳转时也不会附加 Referer 字段信息;
Firefox 始终不在使用 META 元素控制跳转时附加 Referer 字段到请求头中。

造成的影响

若服务端依靠请求头中的 Referer 字段信息进行某些操作,则在使用 META 元素进行页面跳转以及脚本 location 对象进行跳转时在某些浏览器中由于无 Referer 字段而产生差异。

受影响的浏览器

IE6 IE7 IE8  
Firefox  

问题分析

创建一个 Web 服务器,如 Apache。在服务器上编写一段动态代码,用于输出接收到的请求头的 Referer 字段信息。如:refer.php

<?php
  echo '<style>* { font:12px "Trebuchet MS"; }</style>';
  echo (isset($_SERVER['HTTP_REFERER'])) ? 'Referer: ' . $_SERVER['HTTP_REFERER'] : 'Referer: N/A';
?>

本文中将测试 5 种常见的跳转方式,并分别在普通页面及 IFRAME 框架页内测试这些跳转方式下请求头 Referer 字段的发送情况。

5 种跳转方式代码:

anchor.html
<a href="refer.php">Anchor</a>
form_submit.html
<body>
<form action="refer.php"><input type="submit" /></form>
<script>
  document.forms[0].submit();
</script>
</body>
meta.html
<meta http-equiv="refresh" content="1;url=refer.php">
http302.php
<?php
  header('Location: refer.php');
?>
location.html
<script>location.href="refer.php";</script>

测试页面:

index.html
<!DOCTYPE html>
<html>
<head>
<base target="_blank" />
<style>
  * { margin:0; font:16px 'Trebuchet MS'; }
</style>
</head>
<body>
<a href="anchor.html">Anchor</a><br />
<a href="form_submit.html">Form submit</a><br />
<a href="meta.html">META</a><br />
<a href="302.php">HTTP 302</a><br />
<a href="location.html">location.href</a>
</body>
</html>
iframe.html
<!DOCTYPE html>
<html>
<head>
<style>
  * { margin:0; font:16px 'Trebuchet MS'; }
  iframe { width:400px; height:40px; display:block; }
</style>
</head>
<body>
<h1>Anchor:</h1>
<iframe id="anchor" name="anchor" scrolling="no" frameborder="0" src="anchor.html"></iframe>
<h1>Form submit:</h1>
<iframe id="form_submit" name="form_submit" scrolling="no" frameborder="0" src="form_submit.html"></iframe>
<h1>META:</h1>
<iframe id="meta" name="meta" scrolling="no" frameborder="0" src="meta.html"></iframe>
<h1>HTTP 302:</h1>
<iframe id="http302" name="http302" scrolling="no" frameborder="0" src="302.php"></iframe>
<h1>location.href:</h1>
<iframe id="loc" name="loc" scrolling="no" frameborder="0" src="location.html"></iframe>
</body>
</html>

在各浏览器中分别打开上表的 "index.html"、"iframe.html",对于页面 "anchor.html" 需要用户手动点击超链接。

这段代码在不同的浏览器环境中的表现:

  IE6 IE7 IE8 Firefox Chrome Safari Opera
index.html 普通超链接 anchor.html OK OK OK
表单提交 form_submit.html OK OK OK
META 跳转 meta.html Fail Fail OK
HTTP 302 跳转 302.php OK OK OK
脚本 location.href 跳转 location.php Fail OK OK
iframe.html 普通超链接 anchor.html OK OK OK
表单提交 form_submit.html OK OK OK
META 跳转 meta.html Fail Fail OK
HTTP 302 跳转 302.php OK OK OK
脚本 location.href 跳转 location.php OK OK OK

可见,对于普通超链接、表单提交、302 跳转,各浏览器均会在请求头附加 Referer 字段信息,而对于 META 元素控制跳转及通过脚本使用 location 对象进行跳转时:

  •  IE6 IE7 IE8 中,始终不在使用 META 元素控制跳转时附加 Referer 字段到请求头中。在普通页面中,当脚本调用 location 对象进行跳转时也不会附加 Referer 字段信息;

  •  Firefox 中,始终不在使用 META 元素控制跳转时附加 Referer 字段到请求头中;
  •  Chrome Safari Opera 中,则对于测试的 5 种方式下均会附加 Referer 字段信息。

解决方案

若服务端需要获得正确的 Referer 字段信息,则应采用各浏览器均可以附加 Referer 字段信息的方式进行跳转。如,普通超链接、表单提交、HTTP 302 跳转。

Jan21

【转载】getchar()和EOF有关总结

Author: chinaunix  Click: 6340   Comments: 0 Category: Linux C/C++编程  Tag: getchar,eof
getchar()和EOF总结

大师级经典的著作,要字斟句酌的去读,去理解。以前在看K&R的The C Programming Language(SecondEdition)
第1.5节的字符输入/输出,被getchar()和EOF所迷惑了。可能主要还是由于没有搞清楚getchar()的工作原理和EOF的用法。因此,感觉很有必要总结一下,不然,很多琐碎的知识点长时间过后就会淡忘的,只有写下来才是最好的方法。
其实,getchar()最典型的程序也就几行代码而已。本人所用的环境是DebianGNU/Linux,在其他系统下也一样。
一、getchar的两点总结:
1.getchar是以行为单位进行存取的。
当用getchar进行输入时,如果输入的第一个字符为有效字符(即输入是文件结束符EOF,Windows下为组合键Ctrl+Z, Unix/Linux下为组合键Ctrl+D),那么只有当最后一个输入字符为换行符'\n'(也可以是文件结束符EOF,EOF将在后面讨论)时, getchar才会停止执行,整个程序将会往下执行。譬如下面程序段:
while((c = getchar()) != EOF){
putchar(c);
}
执行程序,输入:abc,然后回车。则程序就会去执行puchar(c),然后输出abc,这个地方不要忘了,系统输出的还有一个回车。然后可以继续输入,再次遇到换行符的时候,程序又会把那一行的输入的字符输出在终端上。
对于getchar,肯定很多初学的朋友会问,getchar不是以字符为单位读取的吗?那么,既然我输入了第一个字符a,肯定满足while循环(c = getchar()) != EOF的条件阿,那么应该执行putchar(c)在终端输出一个字符a。不错,我在用getchar的时候也是一直这么想的,但是程序就偏偏不着样执行,而是必需读到一个换行符或者文件结束符EOF才进行一次输出。
对这个问题的一个解释是,在大师编写C的时候,当时并没有所谓终端输入的概念,所有的输入实际上都是按照文件进行读取的,文件中一般都是以行为单位的。因此,只有遇到换行符,那么程序会认为输入结束,然后采取执行程序的其他部分。同时,输入是按照文件的方式存取的,那么要结束一个文件的输入就需用到EOF (Enf Of File). 这也就是为什么getchar结束输入退出时要用EOF的原因。
2.getchar()的返回值一般情况下是字符,但也可能是负值,即返回EOF。
这里要强调的一点就是,getchar函数通常返回终端所输入的字符,这些字符系统中对应的ASCII值都是非负的。因此,很多时候,我们会写这样的两行代码:
char c;
c = getchar();
这样就很有可能出现问题。因为getchar函数除了返回终端输入的字符外,在遇到Ctrl+D(Linux下)即文件结束符EOF时,getchar ()的返回EOF,这个EOF在函数库里一般定义为-1。因此,在这种情况下,getchar函数返回一个负值,把一个负值赋给一个char型的变量是不正确的。为了能够让所定义的变量能够包含getchar函数返回的所有可能的值,正确的定义方法如下(K&R C中特别提到了这个问题):
int c;
c = getchar();
二、EOF的两点总结(主要指普通终端中的EOF)
1.EOF作为文件结束符时的情况:
EOF虽然是文件结束符,但并不是在任何情况下输入Ctrl+D(Windows下Ctrl+Z)都能够实现文件结束的功能,只有在下列的条件下,才作为文件结束符。
(1)遇到getcahr函数执行时,要输入第一个字符时就直接输入Ctrl+D,就可以跳出getchar(),去执行程序的其他部分;
(2)在前面输入的字符为换行符时,接着输入Ctrl+D;
(3)在前面有字符输入且不为换行符时,要连着输入两次Ctrl+D,这时第二次输入的Ctrl+D起到文件结束符的功能,至于第一次的Ctrl+D的作用将在下面介绍。
其实,这三种情况都可以总结为只有在getchar()提示新的一次输入时,直接输入Ctrl+D才相当于文件结束符。
2.EOF作为行结束符时的情况,这时候输入Ctrl+D并不能结束getchar(),而只能引发getchar()提示下一轮的输入。
这种情况主要是在进行getchar()新的一行输入时,当输入了若干字符(不能包含换行符)之后,直接输入Ctrl+D,此时的Ctrl+D并不是文件结束符,而只是相当于换行符的功能,即结束当前的输入。以上面的代码段为例,如果执行时输入abc,然后Ctrl+D,程序输出结果为:
abcabc
注意:第一组abc为从终端输入的,然后输入Ctrl+D,就输出第二组abc,同时光标停在第二组字符的c后面,然后可以进行新一次的输入。这时如果再次输入Ctrl+D,则起到了文件结束符的作用,结束getchar()。
如果输入abc之后,然后回车,输入换行符的话,则终端显示为:
abc //第一行,带回车
abc //第二行
//第三行
其中第一行为终端输入,第二行为终端输出,光标停在了第三行处,等待新一次的终端输入。
从这里也可以看出Ctrl+D和换行符分别作为行结束符时,输出的不同结果。
EOF的作用也可以总结为:当终端有字符输入时,Ctrl+D产生的EOF相当于结束本行的输入,将引起getchar()新一轮的输入;当终端没有字符输入或者可以说当getchar()读取新的一次输入时,输入Ctrl+D,此时产生的EOF相当于文件结束符,程序将结束getchar()的执行。
【补充】本文第二部分中关于EOF的总结部分,适用于终端驱动处于一次一行的模式下。也就是虽然getchar()和putchar()确实是按照每次一个字符 进行的。但是终端驱动处于一次一行的模式,它的输入只有到“\n”或者EOF时才结束,因此,终端上得到的输出也都是按行的。如果要实现终端在读一个字符就结束输入的话,下面的程序是一种实现的方法(参考《C专家编程》,略有改动):
/*Edit by Godbach
CU Blog: http://blog.chinaunix.net/u/33048/
*/
#include stdio.h>
#include stdlib.h>
int
main(void)
{
int c;
/* 终端驱动处于普通的一次一行模式 */
system("stty raw");

/* 现在的终端驱动处于一次一个字符模式 */
c = getchar();
putchar();

/* 终端驱动处又回到一次一行模式 */
system("stty cooked");

return 0;
}
编译运行该程序,则当如入一个字符时,直接出处一个字符,然后程序结束。
由此可见,由于终端驱动的模式不同,造成了getchar()输入结束的条件不一样。普通模式下需要回车或者EOF,而在一次一个字符的模式下,则输入一个字符之后就结束了。
希望本文可以对初学C的朋友提供一点帮助,也希望能和其他朋友进行交流。其中理解不对的地方若能得到指正和建议,本人将不胜感激。同时,本文参考了chinaunix.net关于getchar讨论的帖子和一位博友的文章,链接地址分别为:
http://blog.chinaunix.net/u/9861/showart_64652.html
http://bbs.chinaunix.net/viewthread.php?tid=679688&extra=&page=1
Jan14

shell输入与输出高阶知识点汇总

Author: leeon  Click: 7084   Comments: 0 Category: linux  Tag: bash,shell,stdio,stdout,stderr,io

shell输入输出基本知识点:

 a、I/O重定向通常与 FD有关,shell的FD通常为10个,即 0~9;
b、常用FD有3个,为0(stdin,标准输入)、1(stdout,标准输出)、2(stderr,标准错误输出),默认与keyboard、monitor、monitor有关;
c、用 < 来改变读进的数据信道(stdin),使之从指定的档案读进;
d、用 > 来改变送出的数据信道(stdout, stderr),使之输出到指定的档案;
e、0 是 < 的默认值,因此 < 与 0<是一样的;同理,> 与 1> 是一样的;
f、在IO重定向 中,stdout 与 stderr 的管道会先准备好,才会从 stdin 读进资料;
g、管道“|”(pipe line):上一个命令的 stdout 接到下一个命令的 stdin;
h、tee 命令是在不影响原本 I/O 的情况下,将 stdout 复制一份到档案去;
i、bash(ksh)执行命令的过程:分析命令-变量求值-命令替代(``和$( ))-重定向-通配符展开-确定路径-执行命令;
j、( ) 将 command group 置于 sub-shell 去执行,也称 nested sub-shell,它有一点非常重要的特性是:继承父shell的Standard input, output, and error plus any other open file descriptors。
k、exec 命令:常用来替代当前 shell 并重新启动一个 shell,换句话说,并没有启动子 shell。使用这一命令时任何现有环境都将会被清除,。exec 在对文件描述符进行操作的时候,也只有在这时,exec 不会覆盖你当前的 shell 环境。

 

IO文件描述符:

>&n 使用系统调用 dup (2) 复制文件描述符 n 并把结果用作标准输出
<&n 标准输入复制自文件描述符 n
<&- 关闭标准输入(键盘)
>&- 关闭标准输出
n<&- 表示将 n 号输入关闭
n>&- 表示将 n 号输出关闭
上述所有形式都可以前导一个数字,此时建立的文件描述符由这个数字指定而不是缺省的 0 或 1。如:
... 2>file 运行一个命令并把错误输出(文件描述符 2)定向到 file。
... 2>&1 运行一个命令并把它的标准输出和输出合并。(严格的说是通过复制文件描述符 1 来建立文件描述符 2 ,但效果通常是合并了两个流。)

 

exec命令使用技巧:

exec 0<infilename # 打开文件infilename作为 stdin
exec 1>outfilename # 打开文件outfilename作为stdout
exec 2>errfilename # 打开文件 errfilename作为 stderr
exec 0<&- # 关闭 FD0
exec 1>&- # 关闭 FD1
exec 5>&- # 关闭 FD5

分类

标签

归档

最新评论

Abyss在00:04:28评论了
Linux中ramdisk,tmpfs,ramfs的介绍与性能测试
shallwe99在10:21:17评论了
【原创】如何在微信小程序开发中正确的使用vant ui组件
默一在09:04:53评论了
Berkeley DB 由浅入深【转自架构师杨建】
Memory在14:09:22评论了
【原创】最佳PHP框架选择(phalcon,yaf,laravel,thinkphp,yii)
leo在17:57:04评论了
shell中使用while循环ssh的注意事项

我看过的书

链接

其他

访问本站种子 本站平均热度:8823 c° 本站链接数:1 个 本站标签数:464 个 本站被评论次数:94 次