Windows下非阻塞并发服务器的心得(适合刚学网络编程的小白看呦)

先说明一下,本人是个小白,是电子专业的,也是从C转到C++的初始阶段。现在到企业开始写企业级的代码了呢,感兴趣的小伙伴可以看看呦,保证是小白们第一步遇到的问题


问题:并发服务器架构目前实现的两个版本(其实就是有一点点不一样啦):

1、基本上发挥select函数的特性,将服务端的socket当做文件描述符放入set中,每次循环询问是否为socket,是的话把连接描述符添加进set集合(必须要先询问是否是set集合里面的元素),else就将数据读出来进行处理数据


优点:只要客户端没有断开连接,可以快速处理从客户端发过来的数据,可以处理大量客户端连接的问题,节约了一些资源,


缺点:等到set集合中的连接描述符到达一定个数的时候,轮询set中是否有数据读所花费的时间就不能忽视了,这将导致数据处理的速度降了下来


2、accept到一个连接描述符就开启一个线程去接收数据,当然,也要用到select去看看它后续有没有数据读出来,等待时间随意,但是这样有一些致命的bug,如果有数据过来,一次并没有发完,并且也已经超时了,线程退出,这时候我们收到的数据是不完整的,当数据再来时连接描述符已经改变,接收到的数据和上次的已经连接不上了(现在考虑的是sock_stream),如果是数据包可以指定数据的长度


优点:在大量客户端连接的时候不需要轮询set集合中元素的可读性(我们现在只考虑读事件),提升了读数据的效率


缺点:就上面我说的啦



问题:在每次使用select函数的时候都要把set里的数据重置,也就是将FD_SET(sockClient, &readSet)

写在while(true)循环里,否则你可能要收到一个惊喜,原因是每次我们都会将set集合中的元素进行改动,如果不重置第一次收到数据是可以的,但是后面会收到一个参数错误的bug,这时候你就要检查一下是否是这个原因呦!


问题:我写的代码客户端发送的是两个结构体,一个是消息头,一个是用户数据,这时候你要注意!!!如果我把这两个结构体打一个包发送过去,是140个字节,如果我把它们放到BUF里发送,那么字节数是138,所以在接收数据的时候,一定要知道自己发送了多少个字节!

另外,使用全局变量完成线程间通信,千万要注意,千万要注意,千万要注意,重要的事情说三遍,不要出现死锁现象!按照我的经历来说,如果控制台打印不了其他线程的信息,那么极有可能是死锁造成的原因,为了这个bug我疯了半天的,后来灵机一动才想起来是这个原因造成的,所以提醒一下大家


在Linux中,接收数据的buf最好清零一下,初始化数组为0有可能没用,数据再打印出来的时候还是乱码,所以调用函数把它清零还是有点必要的,比如bzero(),memset(),等,头文件记不清了,可以去man一下。但是在windows下可以不用这么做,直接初始化就够了,具体为啥我也不太清楚,可能是因为内存大小的原因吧


废话不多说,上代码

server:



client :

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值