这周学习了linux网络编程相关的知识,现在将其总结如下:
在linux系统中已经将TCP/IP协议相关的东西都封装好了,所以在入门学习网络编程的时候并没有学习研究太多TCP/IP协议的东西,而是学习那些已经将协议封装好的函数和API。
在linux网络编程中基本几个函数如下:
第一个函数:套接字创建函数
该函数功能是创建一个套接字,各参数含义及函数用法如下
参数_domain表示创建的套接字使用的协议族,其主要取值有:
AF_UNIX:创建一个只在本机内进行通信的套接字
AF_INET:使用IPv4 TCP/IP协议
AF_INET6:使用IPv6 TCP/IP协议
参数_type表示套接字的类型,可以有如下取值:
SOCK_STREAM:创建一个TCP套接字
SOCK_DGRAM:创建UDP套接字
SOCK_RAM:创建一个原始套接字
参数_protocol通常设置为0,表示通过参数_domain制定的协议族和参数_type指定的套接字类型来确定使用的协议。当创建原始套接字时,系统无法唯一地确定协议,此时就需要使用该参数指定所使用的协议。
函数执行成功返回新创建的套接字,失败返回-1,错误代码存入errno中。
第二个函数:建立连接函数
该函数的功能是在指定的套接字上创建一个连接。各参数含义及用法如下
参数__fd是由socket()函数创建的一个套接字,如果该套接字类型是SOCK_STREAM,则connect函数用于向服务器发出连接请求。服务器的IP地址和端口号由参数__addr参数指定,上图中__addr所对应的数据类型是const struct socketaddr *。如果套接字类型是SOCK_DGRAM则调用connect函数并不真正建立连接而只是告诉内核与该套接字进行通信的目的地址(的第二个参数指定),只有该目标地址发来数据时才会被该socket接收。对于SOCK_DGRAM的好处在于不必每次发送数据时都指定目的地址。__len参数表示第二个地址参数的大小。
该函数在使用时需要注意:如果是TCP常连接选项的话只能够调用一次connect函数建立连接,而对于无连接的UDP来说可以多次调用该函数来改变发送数据的目标地址。
第三个函数:绑定端口函数
该函数是将一个端口绑定在某个套接字上,这个函数常用在服务器端。其中__fd表示要绑定的套接字描述符,__addr表示要绑定的IP,__len表示要绑定的IP长度,一般用sizeof计算。
第四个函数:监听函数
该函数是将一个套接字转化为监听套接字,常用于服务器端监听来自客户端的连接请求。第一个参数__fd表示监听套接字描述符,第二个参数表示最大监听的个数。
第五个函数:接受连接函数
这个函数的功能是接收来自监听套接字上的请求,__fd是一个监听套接字,__addr用来保存发起连接的主机的端口号和IP,与上两个函数中的__addr类型相同,__addr_len是__addr所指向的长度,一般使用sizeof计算达到。
该函数返回一个套接字,返回的套接字就是和客户端建立连接的客户端。
第六个函数:发送数据函数
建立连接的目的就是发送数据,linux中发送数据提供了两个函数,一个用于使用TCP来发送数据,一个使用UDP发送数据,这里总结TCP发送数据的函数,因为UDP发送数据的函数和TCP的int sendto(int __fd, const void *__buf, size_t __n, int __flags, __CONST_SOCKADDR_ARG __addr, socklen_t __addr_len)只是多了发送的目标ID和目标ID的长度。
该函数是使用TCP发送数据,__fd表示建立起连接的套接字(accept函数返回的套接字而非listen函数中的套接字),
__buf表示要发送的数据缓存区地址,__n表示发送数据的长度,__flags表示控制选项,一般取0或者以下值:
MSG_OOB:在指定套接字上发送带外数据(所谓带外数据就是指连接双方中的一方发生重要的事情,想要迅速通知对方,这种通知在已排队等待的任何“普通”数据之前发送。带外数据的发送优先级更高,带外数据是映射进现有连接中而不需要重新连接)
MSG_DONTROUTE:通过最直接路径发送数据,而忽略下层协议的路由设置。
第七个函数:接收数据
linux中提供了TCP接收函数和既能接收TCP又能接收UDP数据的接收函数。
两者都能接收的函数为:
该函数的__fd参数表示连接套接字,__restrict __buf表示接收缓存区,__n表示接收缓存区的大小,__flags一般为0其余取值如下:
MSG_OOB:在指定套接字上发送带外数据
MSG_PEEK:之查看数据而不读出数据
MSG_WAITALL:只在接收数据缓存区满的时候才返回。
如果该函数的__addr非空则表示不是面向连接的,__addr_len在调用前表示__addr的长度,调用后将表示__addr的实际大小。
只能接收TCP的函数为:
extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags);该函数只能用于常连接,函数的参数和上边那个函数差不多,少了最后两个参数。
打个比方来理解这些函数的工作吧,服务器就相当于公司的老板(boss),客户端相当于公司的员工,bind函数相当于给老板分配一个办公室,listen函数表示老板在办公室坐在窗边喝着茶等着员工来找他办事,connect函数表示员工主动去找老板谈加工资的事情,accept函数相当于老板将谈工资这个事情分配给了管工资的小老板,然后员工(客户端套接字描述符)和小老板(accept函数返回的套接字)开始了谈工资的工作,而接收函数和发送函数一个可以看成说话一个可以看成听话。