- 英文小册原文地址:beej.us/guide/bgnet…
- 作者:Beej
- 中文翻译地址:www.chanmufeng.com/posts/netwo…
1. 我从哪获取这些头文件资料?
如果你的系统中没有自带这些文件,或许你根本就不需要他们。你得看一下你平台的使用手册。
对了,如果你是为Windows开发程序,你只需要#include <winsock.h>。
2. bind()报“Address already in use”异常怎么办?
你必须对正在监听的socket使用setsockopt()函数,并设置 SO_REUSEADDR 选项。看一下bind()章节和select()章节中的例子,你就明白了。
3. 我该如何获取到系统中已经打开的socket列表?
使用netstat命令。使用细节你需要参考man手册,不过你只要输入下列指令就能获取到一些不错的信息:
$ netstat
4. 我该如何查看路由表(routing table)?
执行route命令(多数的Linux系统是在/sbin下),或者netstat -r指令。
5. 如果我只有一台电脑,我该怎么运行Client/Server程序?我需要连接外网吗?
幸运的事,所有系统都有一个回环(loopback)虚拟网络“设备”,这个设备位于内核中,并假装自己是个网卡(这家伙就是ifconfig中列出的“lo”)。
假设你登陆一台名为“goat”的设备,并在一个窗口中运行了Client程序,在另一个窗口中运行了Server端程序。或者你也可以在后台运行Server程序(用server &),在另一个窗口中运行Client程序。
loopback设备的用处就是,你可以使用 client goat 或者 client localhost (因为“localhost”已经在你的/etc/hosts中定义好了),这样你就可以让client在没有网络的情况下也可以与server通信。
简而言之,不需要改变任何代码,就可以让你的程序在没有网络的单机上运行!
6. 如果远程断开了连接,我该怎么知道呢?
你可以分辨,因为recv()会返回0。
7. 我自己怎么实现“ping”这个小工具?啥是ICMP?我从哪儿能学到更多关于raw scoket和SOCK_RAW的知识?
你对raw socket的全部疑问都可以在 W. Richard Stevens’ UNIX Network Programming books这本书中找到答案。在Stevens’ UNIX Network Programming源代码的ping子目录中,你可以找到ping的源码。
8. 我该如何改变或缩短调用connect()的过期时间?
这个问题 W. Richard Stevens 已经回答了,我们就不狗尾续貂了。你可以参考UNIX Network Programming源代码中的 lib/connect_nonb.c。
其要点是,使用socket()创建一个socket descriptor,将其设置为non-blocking,调用connect(),如果一切顺利,connect()将立即返回-1,errno将设置为EINPROGRESS。然后,你可以调用select(),并在read和write集合中传递socket descriptor。如果没有超时,则表示connect()调用已完成。此时,你必须使用getsockopt()设置SO_ERROR选项,以获取connect()调用的返回值,如果没有错误,该值应该为0。
最后,在你开始通过socket传输数据之前,你可能姜再将其设置为blocking。
这样做有一个好处,就是让你的程序在connecting(连接期间)也可以做别的事情。比如:你可以将timeout设置为500ms,并在每次timeout时更新屏幕上的提示信息,然后再次调用select()。当你调用select()并超时(例如,达到20次)时,你就知道是时候放弃这个连接了。
强烈建议你看看Stevens的源码,找个好例子研究一下。
9. 我该怎么写Windows网络程序?
首先,卸载Windows,然后装一个Linux或者BSD。。。。哈哈哈哈,开个玩笑。
给你个链接,你看一下section on building for Windows 。
10. 我该如何在Solaris/SunOS上编译程序?我进行编译的时候总报linker error
链接器错误发生是因为 Sun 系统不会在套接字库中自动编译。参考一下这篇文章,其中于如何处理这个问题的范例。










