3.深入了解listen函数

在这里插入图片描述

0.往期回顾 (用心写好每一篇文章)

1.深入了解socket函数
2.深入了解bind函数

1.listen函数查看方法

使用指令:man listen

man 指令
man 文档

在这里插入图片描述

2.详细解说(中文)

listen:

1.功能:
listen函数使用主动连接套接字变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。

调用listen导致套接字从CLOSED状态转换到LISTEN状态。

2.函数原型:

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int listen(int sockfd, int backlog);

3.参数说明:

1.sockfd:一个已绑定未被连接的套接字描述符
2.backlog: 规定了内核应该为相应套接字排队的最大连接个数。用SOMAXCONN则为系统给出的最大值

为了理解其中的backlog参数,我们必须认识到内核为任何一个给定的监听套接字维护两个队列:
(1)未完成连接队列。每个这样的SYN分节对应其中一项:已由某个客户发出并到达服务器,而服务器正在等待完成相应的TCP三路握手过程。这些套接字处于SYN_ RCVD状态
(2)已完成连接队列。每个已完成TCP三路握手过程的客户对应其中一项,这些套接字处于ESTABLISHED状态。
在这里插入图片描述
每当在未完成连接队列中创建一项时,来自监听套接字的参数就复制到即将建立的连接中。连接的创建机制是完全自动的,无需服务器进程插手。

在这里插入图片描述

下图所列的各种操作系统下,backlog参数取不同值时已排队连接的实际数
目。7个操作系统被归纳成5列不同的值,可见对backlog的意义的解释是如此多样。
在这里插入图片描述

4.函数返回值:

成功: 0
失败:-1 并设置errno

5.其他参考解释:百度百科

百度百科·listen函数

3.案例分析

运行截图

listen函数调用成功

在这里插入图片描述

案例代码

#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct sockaddr SA;

void init()
{
    printf("server is start\n");
    //创建socked
    int sockfd = socket(PF_INET,SOCK_STREAM,0);
    if(-1 == sockfd)
    {
        perror("socket error\n");
        printf("server not start\n");
        exit(-1);
    }
    printf("socket create OK\n");

    //通信地址
    struct sockaddr_in addr;
    addr.sin_family = PF_INET;
    addr.sin_port = htons(10086);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //绑定端口
    int bin = bind(sockfd,(SA*)&addr,sizeof(addr));
    if(-1 == bin)
    {
        perror("bind error\n");
        printf("server not strat\n");
        exit(-1);
    }
    printf("bind port OK\n");

    //设置监听
    int lst =listen(sockfd,100);
    if(-1 == lst)
    {
        perror("falt listen\n");
        printf("server not start\n");
        exit(-1);
    }
    printf("listen seccess!\n");

}

int main()
{
    init();
    return 0;

}

4.socket文档

LISTEN(2)                                                           Linux Programmer's Manual                                                          LISTEN(2)

NAME
       listen - listen for connections on a socket

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int listen(int sockfd, int backlog);

DESCRIPTION
       listen()  marks the socket referred to by sockfd as a passive socket, that is, as a socket that will be used to accept incoming connection requests using
       accept(2).
       翻译:listen()将sockfd引用的套接字标记为被动套接字,也就是说,该套接字将用于使用accept()接受传入的连接请求。

       The sockfd argument is a file descriptor that refers to a socket of type SOCK_STREAM or SOCK_SEQPACKET.
       翻译:sockfd参数是一个文件描述符,它引用类型为SOCK_STREAM或SOCK_SEQPACKET的套接字。

       The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow.  If a connection request arrives when  the
       queue is full, the client may receive an error with an indication of ECONNREFUSED or, if the underlying protocol supports retransmission, the request may
       be ignored so that a later reattempt at connection succeeds.
       翻译:backlog参数定义sockfd的挂起连接队列可能增长到的最大长度。
       如果连接请求在队列已满时到达,则客户端可能会收到一个错误,并指示ECONREFUNCE,
       或者,如果基础协议支持重新传输,则该请求可能会被忽略,以便稍后重新尝试连接成功。


RETURN VALUE
       On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.
       翻译:成功时,返回0。在出现错误时,返回-1,并正确设置errno。

ERRORS
       EADDRINUSE
              Another socket is already listening on the same port.
              翻译:另一个套接字已在同一端口上侦听。

       EADDRINUSE
              (Internet domain sockets) The socket referred to by sockfd had not previously been bound to an address and, upon  attempting  to  bind  it  to  an
              ephemeral  port,  it  was  determined  that  all  port  numbers  in  the  ephemeral  port  range  are  currently  in  use.   See the discussion of
              /proc/sys/net/ipv4/ip_local_port_range in ip(7).
              翻译:(Internet域套接字)sockfd引用的套接字以前未绑定到地址,
              在尝试将其绑定到临时端口时,确定临时端口范围内的所有端口号当前都在使用中。参见对/proc/sys/net/ipv4/ip\本地\端口\范围在ip(7)中。

       EBADF  The argument sockfd is not a valid file descriptor.
       		  翻译:参数sockfd不是有效的文件描述符。

       ENOTSOCK
              The file descriptor sockfd does not refer to a socket.
              翻译:文件描述符sockfd不引用套接字。
              

       EOPNOTSUPP
              The socket is not of a type that supports the listen() operation.
              翻译:套接字的类型不支持listen()操作
CONFORMING TO
       POSIX.1-2001, POSIX.1-2008, 4.4BSD (listen() first appeared in 4.2BSD).

NOTES
       To accept connections, the following steps are performed:
       翻译:要接受连接,请执行以下步骤

           1.  A socket is created with socket(2).
		       翻译:使用socket创建套接字。

           2.  The socket is bound to a local address using bind(2), so that other sockets may be connect(2)ed to it.
			    翻译:使用bind将套接字绑定到本地地址,以便其他套接字可以connect到它。

           3.  A willingness to accept incoming connections and a queue limit for incoming connections are specified with listen().
				翻译:使用listen()指定接受传入连接的意愿和传入连接的队列限制。
				
           4.  Connections are accepted with accept(2)
           翻译:使用accept接受连接

       POSIX.1 does not require the inclusion of <sys/types.h>, and this header file is not required on Linux.  However, some historical  (BSD)  implementations
       required this header file, and portable applications are probably wise to include it.
       翻译:不需要包含<sys/类型。h> ,并且Linux上不需要此头文件。
       但是,一些历史(BSD)实现需要此头文件,而便携式应用程序可能明智地将其包括在内。

       The behavior of the backlog argument on TCP sockets changed with Linux 2.2.  Now it specifies the queue length for completely established sockets waiting
       to be accepted, instead of the number of incomplete connection requests.  The maximum length of the  queue  for  incomplete  sockets  can  be  set  using
       /proc/sys/net/ipv4/tcp_max_syn_backlog.  When syncookies are enabled there is no logical maximum length and this setting is ignored.  See tcp(7) for more
       information.

       If the backlog argument is greater than the value in /proc/sys/net/core/somaxconn, then it is silently truncated to that value.  Since Linux 5.4, the de‐
       fault  in  this file is 4096; in earlier kernels, the default value is 128.  In kernels before 2.4.25, this limit was a hard coded value, SOMAXCONN, with
       the value 128.

EXAMPLE
       See bind(2).

SEE ALSO
       accept(2), bind(2), connect(2), socket(2), socket(7)

COLOPHON
       This page is part of release 5.05 of the Linux man-pages project.  A description of the project, information about reporting bugs, and the latest version
       of this page, can be found at https://www.kernel.org/doc/man-pages/.

Linux                                                                      2020-02-09  

参考文档
[1] linux man手册
[2]《Linux高性能服务器》
[3]《Unix网络编程卷1》

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

紫荆鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值