在浏览器中打开网页

程序需要用机器上的浏览器打开网页,但不同操作系统与程序交互的方式不同,因此实现起来多少有些难度。

在浏览器中打开网页 - 图1

好在兼职演员已经为你写好了这部分的代码,它能够在绝大多数系统上打开网页。但他们好像还有要事在身,所以只采用了最简单的实现方式:

在浏览器中打开网页 - 图2

代码用了三条命令,它们分别可以在Windows、Linux和 Mac上打开URL。每次都有两条命令会失败,但只要有一条成功就行了。

在浏览器中打开网页 - 图3滑野雪

你能写出比兼职演员更好的代码吗?为何不用fork()exec()在你喜欢的操作系统中重写这部分代码呢?

 

在浏览器中打开网页 - 图4练习

大部分代码已经写好了,你只需要填写用管道连接父子进程的那部分。为了节约空间,我们去掉了#include语句、error()open_url()函数。别忘了,在这个程序中是子进程对父进程说话,所以请以正确的方式连接管道!

在浏览器中打开网页 - 图5

 

在浏览器中打开网页 - 图6练习解答

大部分代码已经写好了,你只需要填写用管道连接父子进程的那部分。为了节约空间,我们去掉了#include语句、error()open_url()函数。

在浏览器中打开网页 - 图7

在浏览器中打开网页 - 图8试驾

编译代码并运行程序,出现了:

在浏览器中打开网页 - 图9

太棒了,程序工作了。

news_opener程序在一个独立的进程中运行了rssgossip.py,并让它显示找到新闻的URL。所有本来应该发送到屏幕上的输出现在通过管道重定向到news_opener父进程,news_opener就可以在浏览器中打开新闻了。

在浏览器中打开网页 - 图10

管道是连接进程的好办法。现在你不但能够运行进程,控制它们的环境,而且还能获取进程的输出,这样就可以实现很多功能。任何一个能够在命令行中运行的程序你都可以在C代码中调用并控制它。

在浏览器中打开网页 - 图11滑野雪

既然你已经知道了如何控制rssgossip.py,为什么不试着控制一些其他程序呢?在类Unix机器或任何使用Cygwin的Windows机器中可以获取以下程序:

curl/wget

可以用这两个程序与网络服务器通信,也可以在C代码中使用它们与网络通信。

mail/mutt

可以在命令行用这两个程序发送邮件。如果在机器上装了它们,C程序就能发送邮件。

convert

convert命令可以转换图片格式。你可以写一个C程序,它输出文本格式的SVG图表,然后用convert命令把SVG转化成PNG图片。

 

这里没有蠢问题

问:管道是文件吗?

:这取决于操作系统创建管道的方式,通常用pipe()创建的管道都不是文件。

问:就是说也有可能是文件?

:你可以创建基于文件的管道,它们通常叫有名管道或FIFO(First In First Out,先进先出)文件。

问:它能干嘛?

:因为基于文件的管道有名字,所以两个进程只要知道管道的名字也能用它来通信,即使它们非父子进程。

问:太好了!怎么使用有名管道?

:使用mkfifo()系统调用,详情请见http://tinyurl.com/cdf6ve5

问:如果不用文件来实现管道,那用什么?

:通常用存储器。数据写到存储器中的某个位置,然后再从另一个位置读取。

问:如果我试图读取一个空的管道会怎么样?

:程序会等管道中出现东西。

问:父进程如何知道子进程什么时候结束?

:子进程结束时,管道会关闭。fgets()将收到EOF(End Of File,文件结束符),于是fgets()函数返回0,循环就结束了。

问:父进程能对子进程说话吗?

:当然可以。你完全可以反向连接管道,让数据从父进程发送到子进程。

问:管道能够双向通信吗?这样父子进程不就可以边听边讲了?

:管道只能单向通信。不过可以创建两个管道,一个从父进程连到子进程,另一个从子进程连到父进程。

 

在浏览器中打开网页 - 图12要点

  • 父子进程可以用管道通信。

  • pipe()函数创建一个管道和两个描述符。

  • 一个描述符是管道的读取端,另一个是写入端。

  • 可以把标准输入和标准输出重定向到管道。

  • 父子进程各自使用管道的一端。