C网络编程接口(三)

一 recv

原型:ssize_t recv(int sockfd, void *buf, size_t len, int flags);
说明:读取 sockfd 上的数据,buf和 len 参数分別指定读缓冲区的位置和大小,flags 参数的含义见后文,通常设置为0 即可。recv 成功时返回实际读取到的数据的长度,它可能小于我们期望的长度 len。因此我们可能要多次调用recv,才能读取到完整的数据。
在这里插入图片描述
返回值:
0:这意味着通信对方已经关闭连接了。
-1:如果在读的过程中遇到了中断那么会返回-1,同时置errno为EINTR。recv 出错时返问-1,并设置 errno。在Unix系统下,如果recv函数在等待协议接收数据时网络断开了,那么调用recv的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。
  在非阻塞模式下,无论操作是否完成都会立刻返回,需要通过其他方式来判断具体操作是否成功。(对于connect,accpet操作,通过select判断,对于recv,recvfrom,send,sendto通过返回值+错误码来判断)

EAGAIN:套接字已标记为非阻塞,而接收操作被阻塞或者接收超时
EBADF:sock不是有效的描述词
ECONNREFUSE:远程主机阻绝网络连接
EFAULT:内存空间访问出错
EINTR:操作被信号中断
EINVAL:参数无效
ENOMEM:内存不足
ENOTCONN:与面向连接关联的套接字尚未被连接上
ENOTSOCK:sock索引的不是套接字

二 getsockopt和setsockopt

  下面两个系统调用则是专门用来读取和设置 socket 文件描述符属性的方法:

#include <sys/socket.h>
int getsockopt(int sockfd, int level, int option_name, void
				*option_value, socklen_t * restrict option_len);
/*restrict,C语言中的一种类型限定符(Type Qualifiers),用于告诉编译器,
对象已经被指针所引用,不能通过除该指针外所有其他直接或间接的方式修改该对象
的内容。*/
int setsockopt(int sockfd, int level, int option_name, const void *
option_value, socklen_t option_len);

  sockfd 参数指定被操作的目标 socket。level 参数指定要操作哪个协议的选项 (即属性),比如IPv4、IPv6、TCP 等。option_name 参数则指定选项的名字。
  以下是 socket 通信中几个比较常用的 socket 选项。 option_value 和 option_len 参数分別是被操作选项的值和长度,不同的选项具有不同类型的值。
在这里插入图片描述

三 非阻塞socket

  1、socket系统调用的第 2 个参数传递SOCK_NONBLOCK标志;
  2、fcntl系统调用的F_SETFL命令。

flags = fcntl(sockfd, F_GETFL, 0);//获取文件的flags值。
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);   //设置成非阻塞模式;
flags  = fcntl(sockfd,F_GETFL,0);
fcntl(sockfd,F_SETFL,flags&~O_NONBLOCK);    //设置成阻塞模式;

//并在接收和发送数据时:将recv, send 函数的最后有一个flag 参数设置成MSG_DONTWAIT
recv(sockfd, buff, buff_size,MSG_DONTWAIT);     //非阻塞模式的消息发送
send(scokfd, buff, buff_size, MSG_DONTWAIT);   //非阻塞模式的消息接受
发布了67 篇原创文章 · 获赞 26 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/essity/article/details/84932560