具有基于连接的套接字类型( SOCK_STREAM,SOCK_SEQPACKET )的accept()系统调用。它为侦听套接字sockfd提取未决连接队列中的第一个连接请求,创建一个新的已连接套接字,并返回引用该套接字的新文件描述符。新创建的套接字未处于侦听状态。原始套接字sockfd不受此调用的影响。
句法:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- sockfd:参数sockfd是已使用socket()创建的套接字,已使用bind ()绑定到本地地址,并在listen ()之后监听连接。
- addr :参数addr是指向sockaddr结构的指针。如通信层所知,该结构用对等套接字的地址填充。返回的地址的确切格式addr由套接字的地址族确定。当addr为NULL时,
什么都没填;在这种情况下,不使用addrlen ,并且也应为NULL。 - addrlen : addrlen参数是一个值结果参数:调用者必须对其进行初始化,以包含addr指向的结构的大小(以字节为单位);返回时,它将包含对等地址的实际大小。
- 返回值:成功时,这些系统调用将返回一个非负整数,该整数是已接受套接字的文件描述符。如果出错,则返回-1,并正确设置errno 。
如果提供的缓冲区太小,返回的地址将被截断;否则,返回的地址将被截断。在这种情况下,addrlen将返回一个大于提供给调用的值。
如果队列上没有待处理的连接,并且套接字未标记为非阻塞,则accept ()会阻塞调用者,直到存在连接为止。如果套接字被标记为非阻塞并且队列上没有挂起的连接,则accept ()失败,错误为EAGAIN或EWOULDBLOCK 。
// C program to show accept system call is blocking call
#include
#include
#include
#include
#include
#define BACKLOG 3
// Driver program
int main()
{
struct sockaddr_in my_addr, peer_addr;
socklen_t peer_addr_size;
int sd, b, l, acc;
my_addr.sin_family = AF_INET;
// Creating socket
sd = socket(AF_INET, SOCK_STREAM, 0);
// Binding
b = bind(sd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in));
if(b > 0)
printf("Binded Successfully\n");
else
printf("Binding Error\n");
// Listening
l = listen(sd, BACKLOG);
if(l > 0)
printf("Listening...\n");
else
printf("Not listening..\n");
peer_addr_size = sizeof(struct sockaddr_in);
// Accept system call
acc = accept(sd, (struct sockaddr *)&peer_addr, &peer_addr_size);
if(acc > 0)
printf("Accepted\n");
else
printf("Not accepted\n");
}
输出:
Binding Successfully
Listening..
accept()调用中的错误
- EAGAIN或EWOULDBLOCK:套接字被标记为非阻塞,并且不存在可以接受的连接。 POSIX.1-2001和POSIX.1-2008允许在这种情况下返回任一错误,并且不需要这些常量具有相同的值,因此可移植应用程序应检查这两种可能性。
- EBADF: sockfd不是打开的文件描述符。
- ECONNABORTED:连接已中止。
- EFAULT: addr参数不在用户地址空间的可写部分中。
- EINTR:系统调用被有效连接到达之前捕获的信号中断;参见signal(7)。
- EINVAL:套接字未监听连接,或者addrlen无效(例如,为负)。
- EINVAL: (accept4())标志中的无效值。
- EMFILE:已达到打开文件描述符数量的每个进程限制。
- ENFILE:已达到系统范围内打开文件总数的限制。
- ENOBUFS,ENOMEM:可用内存不足。这通常意味着记忆
分配受套接字缓冲区限制的限制,而不是受系统内存的限制。 - ENOTSOCK:文件描述符sockfd不引用套接字。
- EOPNOTSUPP:所引用的套接字不是SOCK_STREAM类型。
- EPROTO:协议错误。
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。