- 英文小册原文地址: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。。。。哈哈哈哈,开个玩笑。