int listenfd = socket(int protofamily, int type, int protocol);
listenfd == -1 失败
listenfd > 0 成功
int ret = bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
ret == -1 失败
ret == 0 成功
int ret = listen(int listenfd,int backlog);
ret == -1 失败
ret == 0 成功
int clientfd = accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
clientfd == -1 && errno == EWOULDBLOCK 说明全连接队列中为空
int ret = connect (int sockfd, struct sockaddr * serv_addr, int addrlen)
ret == -1 && errno == EINPROGRESS 正在建立连接
ret == -1 && errno == EISCONN 连接建立成功
ssize_t n = read(int fd,void *buf,size_t count)
n == -1
errno == EWOULDBLOCK 缓冲区为空
errno == EINRT 被信号打断
其他错误需要close
ssize_t n = write(int fd, const void *buf, size_t count);
n == -1
errno == EWOULDBLOCK 写缓冲区已满
errno == EINRT 被信号打断
n == count 数据全部写入成功
检测io
io函数本身可以检测io的状态,但是只能检测一个fd对应的状态;io多路复用可以同时检测多个io的状态;
io函数可以检测具体的状态;io多路复用只能检测出可读、可写、错误、断开等笼统的事件;
具体错误可以使用 io函数read/write 或者 getsockopt()获取
阻塞io和非阻塞io
差别在于,io函数在数据未到达时是否立刻返回
默认情况下,fd是阻塞的,设置非阻塞方法如下:
int flag = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flag | O_NONBLOCK);