accept函数

43 篇文章 0 订阅
42 篇文章 1 订阅

直白一些,它就是监听、获得“远方”的连接消息。


参考一:

原文地址:

http://blog.chinaunix.net/uid-25749806-id-348689.html

13.2.5  accept函数

处于监听状态的服务器在获得客户机的连接请求后,会将其放置在等待队列中。当系统空闲时,将接受客户机的连接请求。接收客户机的连接请求使用accept函数,该函数的具体信息如表13.6所示。

表13.6   accept函数

头文件

<sys/types.h>

<sys/socket.h>

函数形式

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

返回值

成功

失败

是否设置errno

返回新的套接字文件描述符

−1

说明:

accept函数用于面向连接类型的套接字类型(SOCK_STREAM和SOCK_SEQPACKET)。accept函数将从连接请求队列中获得连接信息,创建新的套接字,并返回该套接字的文件描述符。新创建的套接字用于服务器与客户机的通信,而原来的套接字仍然处于监听状态。

accept函数的sockfd参数为监听的套接字描述符。addr参数为指向结构体sockaddr的指针。参数addrlen为addr参数指向的内存空间的长度。

错误信息:

EAGAIN:套接字处于非阻塞状态,当前没有连接请求。

EBADF:非法的文件描述符。

ECONNABORTED:连接中断。

EINTR:系统调用被信号中断。

EINVAL:套接字没有处于监听状态,或非法的addrlen参数。

EMFILE:达到进程打开文件描述符限制。

ENFILE:达到打开文件数限制。

ENOTSOCK:文件描述符为文件的文件描述符。

EOPNOTSUPP:套接字类型不是SOCK_STREAM。



参考二:

原文地址:

http://blog.csdn.net/wangxmin2005/article/details/7581138

accept()函数 

       系统调用 accept() 会有点古怪的地方的!

       你可以想象发生 这样的事情:有人从很远的地方通过一个你在侦听 (listen()) 的端口连接 (connect()) 到你的机器。它的连接将加入到等待接受 (accept()) 的队列 中。

       你调用 accept() 告诉它你有空闲的连接。它将返回一个新的套接字文 件描述符!这样你就有两个套接字了,原来的一个还在侦听你的那个端口, 新的在准备发送 (send()) 和接收 ( recv()) 数据。这就是这个过程! 

       函数是这样定义的: 

[cpp]  view plain copy
  1. #include <sys/socket.h>  
  2. int accept(int sockfd, void *addr, int *addrlen);   

       sockfd 相当简单,是和 listen() 中一样的套接字描述符。

       addr 是个指向局部的数据结构 sockaddr_in 的指针。这是要求接入的信息所要去的地 方(你可以测定那个地址在那个端口呼叫你)。

       在它的地址传递给 accept 之 前,addrlen 是个局部的整形变量,设置为 sizeof(struct sockaddr_in)。  accept 将不会将多余的字节给 addr。如果你放入的少些,那么它会通过改变 addrlen 的值反映出来。 

       在错误时返回-1,并设置全局错误变量 errno。

        现在是你应该熟悉的代码片段。 

[cpp]  view plain copy
  1. #include <string.h>   
  2. #include <sys/socket.h>   
  3. #include <sys/types.h>   
  4. #define MYPORT 3490 /*用户接入端口*/   
  5. #define BACKLOG 10 /* 多少等待连接控制*/   
  6. main()   
  7. {  
  8.     int sockfd, new_fd; /* listen on sock_fd, new connection on new_fd */  
  9.      struct sockaddr_in my_addr; /* 地址信息 */   
  10.     struct sockaddr_in their_addr; /* connector's address information */   
  11.     int sin_size;   
  12.     sockfd = socket(AF_INET, SOCK_STREAM, 0); /* 错误检查*/  
  13.     my_addr.sin_family = AF_INET; /* host byte order */  
  14.     my_addr.sin_port = htons(MYPORT); /* short, network byte order */  
  15.     my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */   
  16.     bzero(&(my_addr.sin_zero),; /* zero the rest of the struct */  
  17.     /* don't forget your error checking for these calls: */   
  18.     bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));   
  19.     listen(sockfd, BACKLOG);   
  20.     sin_size = sizeof(struct sockaddr_in);   
  21.     new_fd = accept(sockfd, &their_addr, &sin_size);   

        注意,在系统调用 send() 和 recv() 中你应该使用新的套接字描述符 new_fd。如果你只想让一个连接进来,那么你可以使用 close() 去关闭原 来的文件描述符 sockfd 来避免同一个端口更多的连接。

        当你第一次调用 socket() 建立套接口描述符的时候,内核就将他设置为阻塞。如果你不想套接口阻塞,你就要调用函数 fcntl():

        通过设置套接口为非阻塞,你能够有效地"询问"套接口以获得信息,但是一般来说轮询不是一个好主意,会浪费cpu时间,

        更好的方法是用 select()方法 去查询是否有数据要读进来

        select()--多路同步 I/O

        select() 让你可以同时监视多个套接口。如果你想知道的话,那么他就会告诉你哪个套接口准备读,哪个又准备好了写,哪个套接口又发生了例外 (exception)。

        int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值