Linux Socket Programming by Example-第十章 标准I/O与Socket

如何使用libc的接口来操作socket?
从设计模式来说,就是简单的桥模式。


具体来说,系统提供了以下接口来封装:
#include <stdio.h>
FILE* fdopen(int fd, const char *mode);


调用好后,就可以通过FILE*接口来访问socket了。


问题的难点在关闭。


我们知道系统的fd是支持dup操作的。
对普通文件来说,由于有引用计数,多次关闭是没有问题的。
但对于socket来说,多次关闭就有冲突了。


如何解决?
书中的建议是从设计上来解决。


比如,我们可以创建2个流句柄,一个用来接收,一个用来发送。


s = socket(PF_INET, SOCK_STREAM, 0);


rx = fdopen(s, "r");
tx = fdopen(dup(s), "w");


对于关闭,可以以下处理:
接收:
shutdown(fileno(rx), SHUT_RD);
fclose(rx);
发送:
fflush(tx);
shutdown(fileno(tx), SHUT_WR);
fclose(tx);


小技巧:
对于errno 为EINTR,通常采用do-while来retry处理。
do {
clearerr(rx);
ch = fgetc(rx);
} while (ferror(rx) && errno == EINTR);


关于缓冲区大小设置,基本和文件I/O差不多,没啥好特别关注的。


接下来,介绍了一个常见工具函数
mkaddr


输入:host_name:service
输出:配置好相应IP与Port的socket_addr


函数实现用到了
strtok 这个函数主要目的是通过分隔符:来获取子字符串。


最后,书本举了一个RPN(逆波兰式计算公式的实现).


RPN在编译器语法分析中很重要。一个很常规的做法就是将
抽象语法树转化为后序表示法(等价于RPN),这样我们很简单
就可以用堆栈来模拟计算了。


比如: 3 + 5 * 2 
假设对应的语法树为:


         +
      3   *
         5  2
则其后缀表示为: 352 *+
操作数stack为 352
操作符stack为  *+


这样我们的处理算法就很简单了:(不考虑优先级)
while(1)
{
如果当前为操作符,并且不是"=" 
       从stack里取相应操作数 (对于2目运算符+来说,就是取2个操作数)
       将计算后的结果放入stack
如果当前为操作数
        将操作数放入stack
如果为"="
        将结果从stack中取出
       如果stack非空,报错
       退出循环
}











Linux Socket Programming by Example-第十章 标准I/O与Socket,布布扣,bubuko.com

Linux Socket Programming by Example-第十章 标准I/O与Socket

上一篇:Hibernate3.3.2 手动配置annotation环境


下一篇:定制属于自己的 linux 内核(Step 2)