服务器端,创建socket,bind绑定套接字后,还需要使用listen()函数让套接字进入被动监听状态,再调用accept()函数,就可以随时响应客户端的请求了

listen() 函数

通过 listen() 函数可以让套接字进入被动监听状态

int listen(int sock, int backlog);  //Linux

sock 为需要进入监听状态的套接字,backlog 为请求队列的最大长度。

当套接字正在处理客户端请求时,如果有新的请求进来,套接字是没法处理的,只能把它放进缓冲区,待当前请求处理完毕后,再从缓冲区中读取出来处理。如果不断有新的请求进来,它们就按照先后顺序在缓冲区中排队,直到缓冲区满。这个缓冲区,就称为请求队列(Request Queue)。

缓冲区的长度(能存放多少个客户端请求)可以通过 listen() 函数的 backlog 参数指定,可以根据你的需求来定,并发量小的话可以是10或者20。

如果将 backlog 的值设置为 SOMAXCONN,就由系统来决定请求队列长度,这个值一般比较大,可能是几百,或者更多。当请求队列满时,就不再接收新的请求,对于 Linux,客户端会收到 ECONNREFUSED 错误,对于 Windows,客户端会收到 WSAECONNREFUSED 错误。

注意:listen() 只是让套接字处于监听状态,并没有接收请求。接收请求需要使用 accept() 函数。

accept() 函数

当套接字处于监听状态时,可以通过 accept() 函数来接收客户端请求。它的原型为:

int accept(int sock, struct sockaddr *addr, socklen_t *addrlen);  //Linux

sock 为服务器端套接字

addr 为 sockaddr_in 结构体变量(使用强制转化为 sockaddr类型的,在前面学bind中有)

addrlen 为参数 addr 的长度,可由 sizeof() 求得。

accept() 返回一个新的套接字来和客户端通信,addr 保存了客户端的IP地址和端口号,而 sock 是服务器端的套接字。后面和客户端通信时,要使用这个新生成的套接字,而不是原来服务器端的套接字。

最后需要说明的是:listen() 只是让套接字进入监听状态,并没有真正接收客户端请求,listen() 后面的代码会继续执行,直到遇到 accept()。accept() 会阻塞程序执行(后面代码不能被执行),直到有新的请求到来。

listen( ) accept( )的更多相关文章

  1. Socket相关函数(1)- socket(), bind(), listen(), accept(), connect(), TCP模型

    tcp_server.c #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #in ...

  2. socket listen/accept

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

  3. TCP回射客户服务器模型(01 socket bind listen accept connect)

    socket函数(安装电话机)头文件:#include<sys/socket.h> int socket(int family,  int type, int protocol); //返 ...

  4. tcp通讯中socket套接字accept和listen的关系

    今天看到一个文章,客户端的connect在服务端调用accept之前,突然想到这可以建立正常的连接么?以前从没细细的思考过listen accept connect之前的关系,带着疑问学习了一下,记录 ...

  5. access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve")

    在开启derby服务出现该错误(测试hibernate 连接数据库时  使用myeclipse2014自带的数据库--windows->show view->other->Myecl ...

  6. [TCP/IP]TCP服务端accept发生在三次握手的哪一个阶段

    TCP服务端accept发生在三次握手之后 客户端socket()==>connect()==>write()==>read()服务端socket()==>bind()==&g ...

  7. .net core 源码解析-web app是如何启动并接收处理请求(二) kestrel的启动

    上篇讲到.net core web app是如何启动并接受请求的,下面接着探索kestrel server是如何完成此任务的. 1.kestrel server的入口KestrelServer.Sta ...

  8. linux c/c++

    string 字符串操作 操作数的都是 ( char * )型,操作数必须是指向字符串的指针("a"),不能是字符('a'),操作时不考虑末尾的'\0'. size_t strle ...

  9. 【转】网络编程socket基本API详解

    转自:http://www.cnblogs.com/luxiaoxun/archive/2012/10/16/2725760.html socket socket是在应用层和传输层之间的一个抽象层,它 ...

随机推荐

  1. 从头到尾说一次 Java 垃圾回收,写得非常好! (转)

    之前上学的时候有这个一个梗,说在食堂里吃饭,吃完把餐盘端走清理的,是 C++ 程序员,吃完直接就走的,是 Java 程序员.

  2. 事件循环(EventLoop)的学习总结

    前言 在学习eventloop之前,我们需要复习一下js的单线程和异步.虽说js是单线程的,但是在浏览器和Node中都做了相应的处理.如浏览器中的web workers(工作线程),Node中的chi ...

  3. npm学习(三)之如何安装本地包、更新本地安装的包、卸载本地安装的包

    如何安装本地包 有两种方式用来安装 npm 包:本地安装和全局安装.至于选择哪种方式来安装,取决于我们如何使用这个包. 如果你自己的模块依赖于某个包,并通过 Node.js 的 require 加载, ...

  4. 企业面试题|最常问的MySQL面试题集合(三)

    分区表的原理 分库分表的原理 延伸: MySQL的复制原理及负载均衡 分区表的工作原理 对用户而言,分区表是一个独立的逻辑表,但是底层MySQL将其分成了多个物理子表,这对用户来说是透明的,每一个分区 ...

  5. mysql复制表结构,复制表数据

    MYSQL 复制表 show create table table_name:查看表的建表语句.该语句包含了原数据表的结构,索引等. 使用 SHOW CREATE TABLE 命令获取创建数据表(CR ...

  6. 使用redis客户端连接windows和linux下的redis并解决无法连接redis的问题

    搭建环境:linux是centos7.4(请注意centos7以下版本的防火墙跟centos7以上的不同,使用redis客户端连接redis时会有区别,建议使用centos7以上版本) 一.下载red ...

  7. centos7部署nagios(二)

    一.Nagios简介 分类: 监控 undefined Nagios是一款开源的电脑系统和网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系 ...

  8. 不要和SB理论

    不要和SB理论,SB会把你拉倒和他和他一样的高度,然后用充分的经验把你打倒!!!

  9. 格兰杰因果 Granger causality

    格兰杰因果关系(Granger causality )是基于预测的因果关系统计概念.根据格兰杰因果关系,如果信号X1“格兰杰Causes”(或“G-Causes”)信号X2,则X1的过去值应该包含有助 ...

  10. Service_Worker XSS

    0x00 简介 Service Worker 是 Chrome 团队提出和力推的一个 WEB API,用于给 web 应用提供高级的可持续的后台处理能力.该 WEB API 标准起草于 2013 年, ...