1:socket编程中采用的协议族主要有两种 :
1>:网络协议族(形式如:AF_INET, PF_INET等)
2>:本地unix域格式的协议族(形式如:AF_LOCAL, AF_UNIX等)
注:协议族的选择体现在 int socket(int domain, inst type, int protocol)函数的第一个参数处。
2:这两种协议族的区别:
1>:本地unix域格式的协议族,只能用于本机(即,客户端和服务器端在同一台机器);而网络协议族
不仅可以用于本机也可以跨网络
2>:本机上的客户端和服务端之间的通讯采用本地unix域格式的协议族要比采用网络协议族的速度快
3>:本地unix域格式的协议族用的也比较广泛,如一些服务器的模块间的通讯(mysql), 再比如管道等。
3:socket通讯的几个关键的函数
1>:send函数,原型, int send(SOCKET s, const char FAR *buf , int len, inf flags)。该函数的详细介绍:
参数s,套接字描述符; 参数buf,存放发送数据的缓冲区; 参数len, 发送数据的长度; 参数flags,标志,一般为0;
该函数的执行流程(同步socket ):
(1):首先比较len与套接字s的发送缓冲区长度的大小(len1),如果len大于len1,那么该函数立即返回SOCKET_ERROR
(2):如果len < len1, 然后send检查协议是否是在发送s的发送缓冲区里的数据,如果是就等待协议将数据发送完,如果协议还没有开始发送s的发送缓冲区里的数据或者s的发送缓冲区是空的,那么send就比较s的发送缓冲区的剩余空间(len2)和len的大小
(3):如果len > len2, 那么send就一值等待协议将s的发送缓冲区中的数据发送完
(4):如果len < len2, 那么就将待发送的数据copy到s的发送缓冲区里
注:send函数只是将待发送的数据copy到套接字s的发送缓冲区里面,而负责将数据传送到通讯的另一端的是协议 。
(5):send函数的返回情况:如果len > len1 直接返回SOCKET_ERROR; send将数据传送到套接字s的发送缓冲区里,而协议在传送数据时,出现网络故障,也返回SOCKET_ERROR
2>:recv函数(同步socket) ,原型, int recv(SOCKET s, char FAR *buf, int len, int fags)
(1):参数说明, buf,表示接受数据的缓冲区,其余的相同
(2):该函数的执行过程,recv先等待套接字s的发送缓冲区的数据被协议传送完毕,如果协议在传送s的发送缓冲区里数据时,出现网络
网络故障,那么recv函数将返回SOCKET_ERROR。如果s的发送缓冲区中没有数据或者被协议成功传送,然后,recv检查s的接收缓冲区,如果接收缓冲区中没有数据或者协议正在接收数据,那么recv函数将一直等待,直到协议将数据接收完毕。如果协议接收数据完毕,那么recv函数就会将s的接受缓冲区中的数据copy到buf中
注:协议接收到的数据可能大于buf的长度,所以在这种情况下要调用几次recv函数才能把s的接受缓冲区中的数据copy完。真正接受数据的是协议。
注:send与协议是有关联的,如果协议在传送数据时出现网络故障,那么send函数将返回SOCKET_ERROR,而recv与协议是没有关联的(个人理解层面)
3>:设置s的发送和接受缓冲区大小的函数 setsocketopt函数,详细资料,待用时online
4>:关闭套接字描述符s的函数有两个close()和shutdown(),区别如下:
len1 int s; // existing socket
len2 int d;
len3 d = dup(s);
len4 close(s); //nothing happens yet
len5 close(d); //last close, so shudown socket
注:close关闭s之后,不会起任何作用(因为还有一个套接字描述符指向该套接字),只有close关闭d之后,才会起作用。
但是:shutdown()函数会立即关闭掉该套接字。
5>: