0
点赞
收藏
分享

微信扫一扫

socket编程的常见问题


  • 英文小册原文地址:​​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 系统不会在套接字库中自动编译。参考一下​​这篇文章​​,其中于如何处理这个问题的范例。

举报

相关推荐

0 条评论