【UNIX网络编程读书笔记】第一章 简介和TCP/IP(第一个程序)

来源:互联网 发布:网络弊大于利反方提问 编辑:程序博客网 时间:2024/05/14 23:51

具备基本的一些网络知识之后,就开始拜读这本大作了;
写博客感觉还是做一个指南,把觉得方便学习这本书的方法和自己学习的过程记录下来,尽量不会涉及琐碎的知识点

Step 1:

下载源码:http://www.unpbook.com/src.html
源码的使用前准备:http://blog.csdn.net/u013398398/article/details/52141512

Step 2:

第一个程序daytimetcpcli的运行:
如果只有一台电脑,开两个终端,一个是server, 一个是client
(文件夹里写好了makefile所以直接make)
server:

make daytimetcpsrv./daytimetcpsrv       // 编译完之后,运行,server端就开始监听了。

client:

make daytimetcpcli./daytimetcpcli 127.0.0.1      //在同一台主机上测试

Step 3:

看源码解析的一些问题

客户端

  • sockaddr_in
    去源码(unp.h)里找这个结构体的实现
    然后发现这一行:
#include    <netinet/in.h>  /* sockaddr_in{} and other Internet defns */

找了半天终于找到源文件(/usr/include/netinet/in.h),但是这个数据结构又依赖了其他一些类库定义…

struct sockaddr_in {    __uint8_t       sin_len;    sa_family_t     sin_family;    in_port_t       sin_port;    struct in_addr  sin_addr;    char            sin_zero[8];};

我先暂且过掉这个数据结构,只知道这个存储了服务端的IP地址和端口号

socket()创建套接字,指定期望的通信协议类型;

int socket(int family, int type, int protocal)

参数:
family指明协议族(协议域)
type指明套接字类型
protocal某个协议类型常值,或者设为0
返回值:
非负描述符 – 成功,-1 – 出错

然后bzero函数是清零这个结构;

地址族为AF_INET(是 IPv4 网络协议的套接字类型);
端口号为13(获取时间的端口号);

然后我自己验证了一下:
argv[0]是 ./daytimetcpcli
argv[1]是 127.0.0.1

htons()
将主机的无符号短整形数转换成网络字节顺序;

inet_pton()
IP地址转换函数,将IP地址由“点分十进制”向“二进制整数”转换

int inet_pton(int af, const char *src, void *dst);

这个函数转换字符串到网络地址,
第一个参数af是地址簇,
第二个参数*src是来源地址,
第三个参数* dst接收转换后的数据。
返回值:
如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0,为正值则正确

connect()
用于建立与指定socket的连接

int connect(int s, const struct sockaddr * name, int namelen);

参数:
s:标识一个未连接socket
name:指向要连接套接字的sockaddr结构体的指针
namelen:sockaddr结构体的字节长度
返回值:
若无错误发生,则connect()返回0。
否则的话,返回SOCKET_ERROR错误
(这里,我觉得第7页下面对socket的描述还是很明晰的,socket只是一个套接口,我们通过socket()函数将协议族,套接字类型,协议类型组合生成sockfd这个整数才是一个套接口描述字,而真正包含地址和端口号信息的是第二个参数,第三个参数标识长度)
这个是我目前瞎理解….

服务端

在客户端程序里面写过的一写东西就不在赘述了

bind()

int bind(int sockfd, const struct sockaddr* myaddr, socklen_t addrlen)

bind函数把一个本地协议地址赋予一个套接字
参数:
第一个参数是一个套接字;
第二个参数是以这个指向特定于协议的地址结构的指针
第三个参数是该地址结构的长度
返回值:
若成功则为0,出错则为-1

listen()
把该套接字转化为一个监听套接字,这一点书上下面讲的很清楚;

accept()

int accept(int sockfd, struct sockaddr* cliaddr, socklen_t* addrlen)

参数:
第一个参数就是上述的监听套接字;
第二个参数是客户端的地址结构的指针;
第三个参数是长度指针;
返回值:
若成功则为非负描述符,若出错则为-1
accept函数为每个连接到本服务器的客户返回一个新描述符

这里列出了一些函数,虽然说UNP后面还是会详细讲到,但是现在为了弄懂程序,查一些基本的用法,有个感性认识,知道每个函数大概干了什么事情,在以后继续深入的时候不会那么陌生

1 0