搜索
bottom↓
回复: 20

网络服务器 处理多客户端socket个数的疑问

[复制链接]

出0入0汤圆

发表于 2016-1-8 20:47:55 | 显示全部楼层 |阅读模式
有个疑问,web server处理多客户端连接的时候,代码一般是这样的:
  1.   server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

  2.     server_address.sin_family = AF_INET;
  3.     server_address.sin_addr.s_addr = htonl(INADDR_ANY);
  4.     server_address.sin_port = htons(9734);
  5.     server_len = sizeof(server_address);
  6.     bind(server_sockfd, (struct sockaddr *)&server_address, server_len);

  7. listen(server_sockfd, 5);
  8. while(1) {
  9.         char ch;

  10.         printf("server waiting\n");

  11. /*  Accept connection.  */

  12.         client_len = sizeof(client_address);
  13.         client_sockfd = accept(server_sockfd,
  14.             (struct sockaddr *)&client_address, &client_len);

  15. /*  Fork to create a process for this client and perform a test to see
  16.     whether we're the parent or the child.  */

  17.         if(fork() == 0) {

  18. /*  If we're the child, we can now read/write to the client on client_sockfd.
  19.     The five second delay is just for this demonstration.  */

  20.             read(client_sockfd, &ch, 1);
  21.             sleep(5);
  22.             ch++;
  23.             write(client_sockfd, &ch, 1);
  24.             close(client_sockfd);
  25.             exit(0);
  26.         }

  27. /*  Otherwise, we must be the parent and our work for this client is finished.  */

  28.         else {
  29.             close(client_sockfd);
  30.         }
复制代码

我知道 socket处理多客户端时 需要fork多个子进程。准确的讲是 n个连接就是n个子进程 ,外加1个父进程 负责继续listen,所以共n+1 个进程。
那 这个socket呢?   对server来说,监听的socket和 传送数据的是同一个吗?还是  两个(一个listen的socket,一个 负责收发数据), 还是 n+1个socket?

我个人感觉应该是 1个啊。举个例子,我们访问web server一般都是80端口,不管你有多少个client去访问啊。
但是 上面代码进程要n+1个,但用同一个socket ,好像不合理啊。


  

出0入0汤圆

发表于 2016-1-8 20:49:42 | 显示全部楼层
使用 select 按需处理

出0入0汤圆

 楼主| 发表于 2016-1-8 20:54:36 | 显示全部楼层
aozima 发表于 2016-1-8 20:49
使用 select 按需处理


这个我知道,但我就是想知道 socket的个数啊。

是不是这样的:
n个client进来,会有 一个server_sockfd 和 n个 client_sockfd。  他们的 本地IP地址和 本地port都一样的。但远端client是不一样的。
所以,从本地的角度讲,socket是同一个的,是这样吗?

出0入0汤圆

发表于 2016-1-8 21:11:45 | 显示全部楼层
imjacob 发表于 2016-1-8 20:54
这个我知道,但我就是想知道 socket的个数啊。

是不是这样的:


三大卷 及 《linux网络编程》 认真看。
client是个新fd,添加到select列表里面去。

出0入0汤圆

 楼主| 发表于 2016-1-8 21:40:27 | 显示全部楼层
aozima 发表于 2016-1-8 21:11
三大卷 及 《linux网络编程》 认真看。
client是个新fd,添加到select列表里面去。 ...


谢谢!我承认 steven的这几本书确实是好书。但我一下子恐怕看不完,到现在为止恐怕只看了第一卷的一部分,当然有空回去看下去

我现在怀疑 :
那些什么client_sockfd, server_sockfd都是int型,就是个句柄,他们确实个数是: n个client进来,会有 一个server_sockfd 和 n个 client_sockfd。
但是这个和 socket 没有直接关系。按照经典的定义,socket 就是ip地址加上 port,这样的话 只会有一个。
也就是说 client_sockfd, server_sockfd 这些是port 更上层的概念了。
这么说, port是 ip上层的概念, client_sockfd, server_sockfd是 port更上层的概念。

出300入477汤圆

发表于 2016-1-9 10:01:40 | 显示全部楼层
imjacob 发表于 2016-1-8 21:40
谢谢!我承认 steven的这几本书确实是好书。但我一下子恐怕看不完,到现在为止恐怕只看了第一卷的一部分 ...

一个完整的TCP socket包含两端的IP和两端的端口。你自己的Server IP是固定的,端口也固定,
但是客户端的IP和端口都不同,所以可以有很多个不同的socket

出0入0汤圆

 楼主| 发表于 2016-1-9 11:03:59 | 显示全部楼层
redroof 发表于 2016-1-9 10:01
一个完整的TCP socket包含两端的IP和两端的端口。你自己的Server IP是固定的,端口也固定,
但是客户端的 ...


恩。对,查了下是这样。
但是这是对 同一个client和 同一个server来说吧。
我关心的是 server来说,我上面的例子中,监听的socket和 传送数据的是同一个吗?难道是这样,  监听的socket是 ( clientip,port1, serverip,serverport), 传送数据的socket是( clientip,port2, serverip,serverport).
举个例子,对web server来说,上面的serverport一般是80.

若是这样,那对上面的程序来说,两个int型的client_sockfd, server_sockfd和上面 两个socket什么关系呢?

出300入477汤圆

发表于 2016-1-9 11:08:34 | 显示全部楼层
imjacob 发表于 2016-1-9 11:03
恩。对,查了下是这样。
但是这是对 同一个client和 同一个server来说吧。
我关心的是 server来说,我上 ...

监听的socket是特殊的,就叫做“监听socket”,它根本就不发数据!
连上一个客户端的时候,accept函数返回一个系统重新生成的数据socket,你收发数据都是在这个数据socket上面进行的。
每个整数socket就是一个socket核心对象的handle,对你来说他就代表一个socket

出0入89汤圆

发表于 2016-1-9 12:06:49 来自手机 | 显示全部楼层
libev网上看看;libuv也一样

出0入0汤圆

 楼主| 发表于 2016-1-9 12:43:38 | 显示全部楼层
本帖最后由 imjacob 于 2016-1-9 12:45 编辑
redroof 发表于 2016-1-9 11:08
监听的socket是特殊的,就叫做“监听socket”,它根本就不发数据!
连上一个客户端的时候,accept函数返 ...


‘每个整数socket就是一个socket核心对象的handle,对你来说他就代表一个socket’。 

这句话就是我要的话,谢谢! 
这样来说,我有如下的理解,恳请再指点一下,万分感激。

socket 中 IP和 port都是TCPip中的概念,但是 client_sockfd, server_sockfd 不是 ,是为了应用的需要,更具体的是分离 ‘监听’和‘收发数据’的需要而产生的。

所以,按自底向上的关系来说, socket中 IP是 IP层的东东,port是TCP层的东东,而client_sockfd, server_sockfd句柄是 应用的东东,他们是从低往高的。

出1070入962汤圆

发表于 2016-1-9 13:54:53 | 显示全部楼层
每个socket其实是个五元数,(源IP,源端口,目标IP,目标端口,协议),只要这5元里边有一个不同,就被认为是不同的SOCKET。
所以不管是什么系统来实现,都是按照这样的原则进行识别处理的。
socket是个静态的标识,在fork的套路里边,每个进程对应一个socket进行处理。如果你看看winsock2.0的库,会发现微软允许一个线程
对应多个socket进行处理。这样的处理效率更高。

TCPIP协议的分层不像ISO网络分层模型那样严谨,是因为要考虑效率,实现的方便性,事实上TCPIP已经成为了世界标准,但是没有一个严格遵循
ISO7层模型的协议能够成功。

出0入0汤圆

 楼主| 发表于 2016-1-9 21:20:33 | 显示全部楼层
aozima 发表于 2016-1-8 20:49
使用 select 按需处理

你好,能请教下 ,select 能够同时处理 read和write的同时访问吗,能的话,如何处理比较好呢?

出0入0汤圆

发表于 2016-1-9 22:23:04 | 显示全部楼层
微软的那个一个线程处理多个socket的技术,叫做IOCP(IO完成端口)。
自己查查这方面的资料。

出0入24汤圆

发表于 2016-1-9 22:29:15 | 显示全部楼层
协议一下,长知识!

出0入0汤圆

 楼主| 发表于 2016-1-10 14:41:25 | 显示全部楼层
本帖最后由 imjacob 于 2016-1-10 14:48 编辑

看了Appcat,redroof,aozima 的解答多有启发,感谢。
我自己总结一下,简单的说,答案应该是 n+1个socket,其中1个是 ‘监听’socket,其他每个对应着 一个client。

因为像Appcat所说,每个socket其实是个五元数,(源IP,源端口,目标IP,目标端口,协议),只要这5元里边有一个不同,就被认为是不同的SOCKET。
我们这里的这些socket中除了 ‘监听’socket 比较特殊, 是没有第三第四项的。 其他n个socket 5个元素都有,区别仅是目标IP不一样。

具体分析,listen是不阻塞的,创建了等待列表,允许操作系统开始接收客户,完成连接阶段并把它们放入等待被服务的列表。
然后,server开始循环并逐一 对客户进行服务。在每次循环中,server进程 调用accept函数, 从已经连接客户的等待列表中去除一个客户,对其进行服务。

有如下图供参考(只有一个客户端的情况,多客户端的情况增加s套接字)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-8-31 14:43:29 | 显示全部楼层
   mark            

出870入263汤圆

发表于 2016-9-15 14:12:06 | 显示全部楼层
本帖最后由 armstrong 于 2016-9-15 14:15 编辑
imjacob 发表于 2016-1-8 20:54
这个我知道,但我就是想知道 socket的个数啊。

是不是这样的:


负责任的告诉你:你的理解是正确的。

server端,会有1个listen-socket和n个client-socket。server端协议栈单独管理这n个socket,跟其它socket并无二致。每个socket都维护自己的状态机和缓冲区。

出0入211汤圆

发表于 2016-9-15 20:41:09 来自手机 | 显示全部楼层
楼主的问题,表示持续关注
我试过用线程池(表示不懂),实现过带了几十个客户端,没什么问题,搞单片机的真的没办法理解线程池,但是微软就是牛逼,硬是让我这种外行都实现了功能

出0入0汤圆

发表于 2016-9-15 20:52:42 | 显示全部楼层
对于一个固定的服务器端口来说,理论上是65536个终端,但是其中一部分被服务器自身用了,所以会略小于这个数。

出0入4汤圆

发表于 2017-2-6 21:30:30 | 显示全部楼层
mark!

出90入4汤圆

发表于 2017-2-6 21:32:58 | 显示全部楼层
epoll???? 不可以?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 20:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表