Beej's Guide to Network Programming是一个网络编程的入门教程,感觉覆盖还算全面吧,至少对我这种小白来说。
本科网络实验老师给的参考资料,当时没看,现在补回来。
网络版的地址:http://beej.us/guide/bgnet/output/html/multipage/index.html
能找到的中文翻译严重过期,所以直接看英文。(囧,看了大量美剧后,本码农的英文总算是可以把这篇东西顺下来了)
1.recv返回0
tcp,一端断开连接,另一端recv返回0,表示连接断开。(recv返回-1表示出错)
2.循环发送接收,包头要有长度信息
tcp,send想要发送的包的长度和返回成功发送的长度可能不一样。recv同样,发送端一次性发送的东西,接收端大概也不能保证一次收到。所以send和recv都要循环!所以包头一定要有长度信息!
3.select()很好用的样子
4.数据传输格式,可移植性,数据打包
自己以前写东西的时候,都是直接打包数据为struct,发送端直接取struct指针,发送长度sizeof(struct),相同平台相同编译器配置当然没问题,如果跨平台的话就麻烦了。
a.机器字的大端小端存储
b.float,double的存储格式
c.struct字节对齐导致填充字节可能不同
5.广播,UDP区别
IPv6,不支持广播,但是有一个叫做 multicasting的东西。IPv4,只有UDP有广播。囧,这个当然,tcp是一对一连接,怎么广播呢。区别:
1.地址255.255.255.255或者(network_number | (~ netmask))(即地址中代表主机的位全置为1)
2.对socket调用如下代码
// this call is what allows broadcast packets to be sent:
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast,
sizeof broadcast) == -1) {
perror("setsockopt (SO_BROADCAST)");
exit(1);
}
6.Address already in use
调试的时候,这个挺烦的,如果不想等上一分钟,可以试着用如下代码
int yes=1;
//char yes='1'; // Solaris people use this
// lose the pesky "Address already in use" error message
if (setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
7.AF_INET 和 PF_INET
Once upon a time, a long time ago, it was thought that maybe a address family (what the "AF" in "AF_INET"stands for) might support several protocols that were referred to bytheir protocol family (what the "PF" in "PF_INET" standsfor). That didn't happen. And they all lived happily ever after, TheEnd. So the most correct thing to do is to useAF_INETin yourstruct sockaddr_in and PF_INET inyour call tosocket().
8.write a server that accepts shell commandsfrom a client and executes them
注意安全
9.promiscuous mode
当网卡为此模式时,可以作为sniffer用
10.书单+=
"The Practice ofProgramming" by Kernighan and Pike
W. Richard Stevens' UNIX Network Programming