1、引子
在C语言里,想要使用TCP/IP协议来实现一个客户端,必须要遵循以下步骤:
1)创建一个socket。
int socket(int family, int type, int protocol)
函数需要三个参数,分别是协议族的编号,socket的类型,和具体的协议类型。如果初始化时还有印象的话,我们的TCP/IP协议族属于PF_INET,而TCP socket则属于STREAM_SOCK,protocol这个参数一般是0,使用系统中该socket默认的协议类型。如STREAM_SOCK对应的默认协议就是TCP协议。这里只是内核里面的宏,具体到函数库中,可能会有别的表现形式。
函数执行完成,没有错误时,会返回一个int类型的变量,这个变量是socket的ID,与文件ID类似,后续的工作,都是通过对它的引用来开展的。
2)调用connect函数来连接到远程的服务器。
int connect(int sockfd, const struct sockaddr * addr, socklen_t addrlen)
sockfd 就是1)中生成的socket ID。
addr 类型为struct sockaddr,用来描述一个socket的数据结构。这里addr表示要连接的远程服务器的socket描述,包括其服务器的IP地址和端口。
当connect调用完成,没有发生错误时,socket已经完成了TCP/IP协议中的三次握手与服务器端的socket建议了连接。
我感兴趣的是TCP/IP如何完成的这样的一个过程。有了前面的初始化的基础,梳理它的工作流程显得没有那么困难。
2、创建
socket创建函数来自于一个glibc中,glibc是GNU版本的C函数库。C程序里的socket函数怎么到的系统调用,暂且不说。目前只需要最后进入内核的途径如下:
sys_socket(a0, a1, a[2]) net/socket.c 1202
sock_create(family, type, protocol, &sock) net/socket.c
sock_map