1. accept
int clientfd = accept(listenfd, addr, sz);
clientfd == -1 && errno == EWOULDBLOCK
说明的全连接队列为空,
全连接队列的大小可以如下设置
listen(listenfd, backlog); //backlog就是全连接队列的大小
返回值的作用: 1. 检查IO 2. 操作IO,取出全连接队列的fd.
2. connect
int connfd = socket(AF_INET, SOCK_STREAM, 0);
int ret = connect(connfd, (struct sockaddr *)&addr, sizeof(addr));
errno == EINPROGRESS 正在建立连接 //非阻塞IO,
errno == EISCONN 建立连接成功 //非阻塞IO,
3. 连接的断开
主动关闭
close(fd);
shutdown(fd, SHUT_RD);//主动关闭本地读端,对端写段关闭
shutdown(fd, SHUT_WR);//主动关闭本地写段,对端读端关闭
被动关闭
// 被动:读端关闭
int n = read(fd, buf, sz);
if (n == 0) {
close_read(fd);
// close(fd);
}
// 被动:写端关闭
int n = write(fd, buf, sz);
if (n == -1 && errno == EPIPE) {
close_write(fd);
// close(fd);
}
4. 消息的到达: 从缓冲区中读数据
int n = read(fd, buf, sz);
if (n < 0) { // n == -1
if (errno == EINTR || errno == EWOULDBLOCK)
break;
close(fd);
} else if (n == 0) {
close(fd);
} else {
// 处理 buf
}
5. 消息的发送: 往写缓冲区写数据
int n = write(fd, buf, dz);
if (n == -1) {
if (errno == EINTR || errno == EWOULDBLOCK) {
return;
}
close(fd);
}
6. 设置非阻塞IO
// 默认情况下, fd 是阻塞的,设置非阻塞的方法如下;int flag = fcntl ( fd , F_GETFL , 0 );fcntl ( fd , F_SETFL , flag | O_NONBLOCK );
阻塞IO和非阻塞IO的区别: 就是阻塞IO函数当在数据未到达时是否立刻返回。