您的位置:首页 > 理论基础 > 计算机网络

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

2011-09-03 23:13 661 查看
假期闲来无事,便写了个小小的网络聊天室程序。以前一直都是写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,这个写集合,大家也可以上网查查,这里就不过多的介绍了。

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

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

谢谢你的阅读,对于文章的不理解,可以给我留言。也可以给我提出意见,让我写出更好的博文。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐