使用socket实现基于select模型的网络聊天室

假期闲来无事,便写了个小小的网络聊天室程序。以前一直都是写MFC的有界面的程序,时间长了,便失去了兴趣,感觉有些东西经过MFC的封装,反而失去了意义,让人学不到东西,所以,丢开MFC那层的东西,直接使用socket来实现,要知道直接在黑白屏下实现有界面的那种效果,难度还是有的,喜欢挑战自我,是我的个性。

网络程序,有一些I/O模型的,阻塞的,就是你什么也不做的,就是直接开始写的recv和send的,有一个线程阻塞,所以,对对于聊天室来说,这种是不合适的;还有的就是非阻塞了,非阻塞I/O的模型很多了,而select模型,是我这次程序中用到的。

select模型

见名思意,select模型,就是使用了select函数,使用select函数,采用一种有序的方式,对多个套接字进行管理。select函数可以判断一个套接字上是否可以进行读取,或者是否可以在一个套接字上进行写入。这样就有一个好处,那就是,我们可以进行检查某一个套接字上是否可以读取,或者写入,那样的话,就不用一直在阻塞那里等待有数据进入或者有数据发送出去。

select函数详解

int select(int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR * exceptfds, const struct timeval FAR * timeout);

其中最重要的是fd_set参数,这个是某些特定套接字的集合。大家一定要特别的理解这个集合。其它的函数,我在这里就不详细解释了,大家可以查查。fd_set集合,就是满足一些特定条件的套接字,有读的,有写的,有带外数据的。

readfds集合:

条件一:有数据可以读入

条件二:连接已经被关闭、重启或者终止

条件三:假如已经调用了listen,而且有一个连接正处于搁置状态,那么accept函数调用就会调用成功。

以上的三个条件,满足一个就ok了,其实,条件一和条件三,我个人认为是最重要的,条件二貌似可以忽略的,至少看了这么多文章我还是没有看到利用条件二而判断的。所以在这里,大家要深入了解这条件一和条件三的用法。就这么两个条件放在这里,好动,确实很难懂的。我现在给大家详细的说一下。

条件一是指有一个套接字结合,FD_SET集合,这个集合中,是可能有数据输入的套接字集合,说不定,某一个时刻,某一个套接字中就有数据就可以读入了,所以说,我们要不断的循环,select出可以读入的套接字。

看下面的代码:

while (1) { memset(recv_buf, 0x00, sizeof(recv_buf)); FD_ZERO(&readfd); FD_SET(ClientSocket, &readfd); if (select (0, &readfd, NULL, NULL, &tv) == SOCKET_ERROR) { continue; } //recv message if (FD_ISSET(ClientSocket, &readfd)) { if (recv(ClientSocket, recv_buf, sizeof(recv_buf), 0) >= 0) { ...... } else { break; } } } 上面的代码就很能说明第一个条件。

再来说说第三个条件吧。

这个结构和上面的是一样的,但是,你要注意是在listen就绪的情况下,如果有可以accept的套接字,便可以进行套接字的。我推荐一篇文章吧:服务器Select模型的实现。这篇博文不错,相信给大家的理解select有帮助。

还有writefds,这个写集合,大家也可以上网查查,这里就不过多的介绍了。

把我的这个小程序的源代码下载地址贴上吧:单机这里进入下载页面

最后祝大家有个愉快的周末,属于程序员的周末。

谢谢你的阅读,对于文章的不理解,可以给我留言。也可以给我提出意见,让我写出更好的博文。

转载于:https://www.cnblogs.com/JPAORM/archive/2011/09/03/2509880.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值