网络通信的高级函数
1、recv和send
函数原型:
int recv(int sockfd,void *buf,int len,int flags); int send(int sockfd,void *buf,int len,int flags);
前面的三个参数和read、write一样,第四个参数可以是0或者是以下的组合:
MSG_DONTROUTE | 不查找路由表 |
MSG_OOB | 接收或者发送外带数据 |
MSG_PEEK | 查看数据,并不从系统缓冲区移走数据 |
MSG_WAITALL | 等待所有数据 |
MSG_DONTROUTE:send函数使用的标志。这个标志告诉IP协议,目的主机在本地网络上面,没有必要查找路由表。这个标志一般用网络诊断和路由程序里面。
MSG_OOB:表示可以接收和发送带外的数据。
MSG_PEEK:recv函数的使用标志,表示只是从系统缓冲区中读取内容,而不清除系统缓冲区的内容。这样下次读的时候,仍然是一样的内容。一般在有多个进程读写数据时可以使用这个标志。
MSG_WAITALL:recv函数的使用标志,表示等到所有的信息到达时才返回。使用这个标志的时候recv回一直阻塞,直到指定的条件满足或者是发生了错误。
1)当读到了指定的字节时,函数正常返回.返回值等于len 。
2)当读到了文件的结尾时,函数正常返回.返回值小于len 。
3) 当操作发生错误时,返回-1,且设置错误为相应的错误号(errno)。
如果flags为0,则和read、write一样的操作。
2、recvfrom和sendto
五、用户数据报传输(UDP)中已经讲到,在此不再解释。
3、recvmsg和sendmsg
函数原型:
int recvmsg(int sockfd,struct msghdr *msg,int flags); int sendmsg(int sockfd,struct msghdr *msg,int flags);
struct msghdr { void *msg_name; int msg_namelen; struct iovec *msg_iov; int msg_iovlen; void *msg_control; int msg_controllen; int msg_flags; }; struct iovec { void *iov_base; /* 缓冲区开始的地址 */ size_t iov_len; /* 缓冲区的长度 */ };
msg_name和msg_namelen当套接字是非面向连接时(UDP),它们存储接收和发送方的地址信息。
msg_name实际上是一个指向struct sockaddr的指针。
msg_namelen是结构的长度。当套接字是面向连接时,这两个值应设为NULL 。
msg_iov和 msg_iovlen指出接受和发送的缓冲区内容。msg_iov是一个结构指针,msg_iovlen指出这个结构数组的大小。
msg_control和msg_controllen这两个变量是用来接收和发送控制数据时的msg_flags指定接受和发送的操作选项,和 recv、send的选项一样。
4、套接字的关闭
关闭套接字有两个函数close和shutdown。
用close时和我们关闭文件一样:close(sockfd);
shutdown的函数原型为:
int shutdown(int sockfd,int howto);
TCP连接是双向的(是可读写的)。当我们使用close时,会把读写通道都关闭,有时侯我们希望只关闭一个方向,这个时候我们可以使用shutdown。针对不同的howto,系统回采取不同的关闭方式:
- howto=0 这个时候系统会关闭读通道.但是可以继续往接字描述符写。
- howto=1 关闭写通道,和上面相反。
- howto=2 关闭读写通道,和close一样在多进程程序里面。如果有几个子进程共享一个套接字时。如果我们使用shutdown, 那么所有的子进程都不能够操作了,这个时候我们只能够使用close来关闭子进程的套接字描述符。