相对于传统的Unix IPC,socket是更为一般的进程间通信机制;AT&T致力与修改已存在的Unix通信机制,还是局限于单机,而BSD看的更远,开发了Socket机制;
(1)在sys_socketcall()中,第一个参数call即为具体的操作码,而参数args为指向一个数组的指针;根据具体操作码的不同,需要从用户空间复制参数的数量也不同;操作码的分类大体有以下几个方面;
(1.1)插口的创建和删除,SYS_SOCKET,创建一个插口,用户层的socket是其界面;SYS_BIND,代表着一个插口的打开文件号与某个域的可寻址实体和插口地址相结合,用户层的bind是其界面;SYS_SOCKETPAIR,创建一对已经互相连接的无名插口,类似于pipe(),用户层的界面是socketpair();SYS_SHUTDOWN,部分或全部关闭一个插口,用户层的界面是shutdown();
(1.2)插口间连接的建立,有连接模式通信的双方是不对称的,是server/client之间的关系,而连接的建立则需要通过一些步骤,SYS_LISTEN,server一端首先通过listen向内核挂号,用户界面就是listen;SYS_CPNNECT,在有连接模式中,client一方要通过connect向已挂号的server方插口请求连接,具体就是connect函数;SYS_ACCEPT,server方通过accept()接受或等待接受到来的第一个连接请求,用户界面就是accept()函数;
(1.3)有连接模式的报文发送和接收,有连接一定要在client和server双方建立起以后才能用于通信,可以使用read()和write();除此以外,还有recv()/send(),recvfrom()/send_to(),recvmsg()/sendmsg(),这三族库函数也可以用于无连接模式;
(1.4)无连接模式的报文发送和接收,无连接模式的插口不需要事先建立连接,插口一旦建立就可马上发送和接受报文,由于无连接模式是不可靠的,也不一定保持原有的次序,所以不用read和write()这样的有序字节流来操作无连接模式的插口;而是要用上述的三种库函数来操作;SYS_SENDTO,无连接模式插口一旦建立,以后就可以通信了,而无需建立连接,用户界面就是sendto(),to为NULL,tolen为0时,sendto()也就表示有连接;SYS_SEND主要是为了send()来设计的,这里并没有提供地址,因为有连接,预先已经准备好了,但是无连接模式,也可预先设置好地址,通过send来发,这样connect也就仅仅是只是记住了对方的地址,发送报文再从这个地址来取;而有连接还要包含序列号;SYS_SENDMSG,是对前两个函数的增强,用户界面是sendmsg(),其中每个msghdr数据结构代表着一个报文,msg_name为对方的插口地址,msg_iov则指向一个结构数组,该数组中的每一个元素都是一块数据,这样一个报文就可以分散在若干个互不连续的缓冲区中了,适合两种模式;SYS_RECV,SYS_RECVFROM,SYS_RECVMSG是从某个插口s中接收报文的;
(1.5)控制以及辅助性的操作,SYS_GETSOCKNAME,库函数getsockname()用来获取为一个插口s指定的地址或名字,用户界面就是getsockname();SYS_GETPEERNAME是用来获取插口s的对方插口的地址;而SYS_SETSOCKOPT和SYS_GETSOCKOPT,用来设置一些可选项;
(2)具体的通信流程,可用进程间通信示意图如下: