`
xvn57xvn
  • 浏览: 12233 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Select 模型的使用 简单聊天室的实现

 
阅读更多

Select 模型的使用 简单聊天室的实现
2010年07月31日
  Select 模型的使用,简单聊天室的实现
  select模型是一种非阻塞的I/O 模型,他主要是使用select来同时管理多个套接字,如果没有网络事件发生,它边进入等待状态,以便执行同步IO;它的好处在于一个线程可以同时管理多个连接的套接字,这样避免了线程的膨胀。
  要使用selcet模型的步骤:
  1. 创建socket  
  2. socket 通过bind绑定本地地址
  3. socket  监听
  到这里,都是跟阻塞模式的一模一样,下面是不同的
  4.设置套接字的模式为阻塞
  u_long value=1;
  iRet=ioctlsocket(socket_listen,FIONBIO ,&value);       5. 调用select 函数     intselect(
  intnfds,
  fd_set*readfds,
  fd_set*writefds,
  fd_set*exceptfds,
  const struct timeval*timeout
  );           第一个参数是设为0,不管。第二,三,四个参数都是一个套接字的集合,第二个参数是检测套接字的可读性,第三个检测可写性,第四个检查错误。 第五个设置超时时间,如果为NULL,那么永远等待。第二,三,四个参数不能全为NULL,可以允许其中两个为NULL.
  失败返回SOCKET_ERROR也就是-1,如果超时返回0
  所以,判断是否成功,只要判断返回值是否>0就OK。
  select 方法返回后,会在相应的套接字集合fd_set中移除没有网络事件发生的套接字 。
  readfds等待的网络事件:
  1.如果是监听套接字,那么说明有一个连接未决,需要调用accept
  2.如果是普通套接字,有数据可读,需要调用recv
  3.如果是普通套接字,连接关闭,重启,或者 中断       
  writefds等待的网络事件:
  1.数据能够发送
  2.如果一个非阻塞连接调用正在处理,连接已经成功
  exceptfds等待的网络事件:
  1.如果一个非阻塞连接调用正在处理,连接失败
  2.OOB 数据可读
  下面是一个通过Selcet模型来写的类似聊天室的小程序:
  服务器端代码:       // 启动 选择模型的非阻塞 服务器 bool ServerClass::StartSelectServer(int Type, sockaddr_in sin) { SOCKET socket_listen=socket(AF_INET,Type,0); if (socket_listen==INVALID_SOCKET) { coutsocket失败"socket成功"SOCKET client_socket; sockaddr_in client_addr; int addr_len=sizeof(sockaddr_in); //所有要检测的socket,用来跟selcet后的进行对比 fd_set set_server; FD_ZERO(&set_server); FD_SET(socket_listen,&set_server); fd_set set_read; while (true) { coutsocket set_read=set_server; if (select(0,&set_read,NULL,NULL,NULL)>0) { //cout返回"结果 for (int i=0;isocket添加到set_server中去 //这样以后就可以用selcet检测到 来自客户端的数据了。 FD_SET(client_socket,&set_server); string strTemp=inet_ntoa(client_addr.sin_addr); strTemp.append("::"); char szFormat[20]; strTemp.append( ltoa( ntohs(client_addr.sin_port),szFormat,10)); m_addr_name_map[client_socket]=strTemp; } } else { cout发送给其他的clients DispatchToAllClients(set_read.fd_array[i],strOut); } } else { cout返回"SOCKET,string>来表示对应关系。
  同时,为了实现聊天室的效果,也就是一个人发送消息到服务器,服务器应该分发他的这个消息到所有的其他的客户端,所以增加了一个DispatchToAllClients函数
  代码如下:       // 分发消息到所有的客户端 bool ServerClass::DispatchToAllClients(SOCKET self,string strMessage) { mapSOCKET,string>::iterator iter_begin=m_addr_name_map.begin(); mapSOCKET,string>::iterator iter_end=m_addr_name_map.end(); for (;iter_begin!=iter_end;++iter_begin) { if (iter_begin->first!=self) { //如果不是发送消息的客户端本身,那么发送消息 send(iter_begin->first,strMessage.c_str(),strMessag e.length(),0); } } return true; }       下面是客户端的实现:
  客户端通过一个循环来获得用户的输入,如果有输入,并且不是"quit"和"exit",那么就发送消息到服务器。
  同时为了接受服务器转发的其他Clients发送的消息,创建了一个线程,也是用select模型来等待服务器的read网络事件,如果等待到了,就recv,实现了对服务器的消息的接收已经本身消息的发送的同时进行。
  客户端代码:       // 启动客户端 bool ClientClass::StartClient(int Type, sockaddr_in addr) { m_socket_client=socket(AF_INET,Type,0); if (m_socket_client==INVALID_SOCKET) { coutsocket失败"socket成功"发送消息 gets(buffer); str=buffer; if ( (strcmp(str.c_str(),"quit")==0) || (strcmp(str.c_str(),"exit")==0) ) { break; } else { SendMessageToServer(str); } } CloseClient(); return false; }      发送消息到服务器的函数SendMessageToServer实现      // 发送消息到服务器 bool ClientClass::SendMessageToServer(string strMessage) { if (m_socket_client==INVALID_SOCKET) { cout0) { cout发送消息"发送消息"m_socket_client,&set_client); fd_set set_read; //接收消息 char buffer[MAX_PATH]; while (true) { set_read=set_client; if (select(0,&set_read,NULL,NULL,NULL)>0) { for (int i=0;i0) { cout<<buffer<<endl; } } } } }
分享到:
评论

相关推荐

    网络聊天室(socket中的select模型)

    网络聊天室(socket中的select模型) 服务器、客户端 有点像qq群组

    C++ select模型 异步SOCKET 聊天室服务服客户端

    C++ 使用select模型的异步SOCKET通信 聊天室,分为服务器和客户端,简单通信模型,初熟悉select模型

    UDP协议的select模型代码

    基于UDP协议的select模型代码,解决许多初学者,不知道UDP套接字,select模型的疑问!

    网络聊天室(Select异步I/O模型)

    聊天室主要实现功能有: 采用UDP单播通信方式,包括服务器端和客户端。 首先启动服务器端,客户端通过用户名和密码登录服务器,服务器响应客户端登录并提示有用户登录,此时两个用户就可以进行聊天。 界面设计使用...

    MFC局域网聊天室(C++)

    自己编的,用最简单的SELECT模型和多线程技术实现的,还有许多不足之处,但是能实现基本的私聊,群聊,服务器广播功能,我会在以后加以改进。

    MFC网络聊天室.zip

    C++网络编程期末作品 Select模型 SOCKET编程 MFC一对多聊天室 MFC套接字编程

    select聊天室

    select选择模型的聊天程序 聊天室 聊天软件

    TCP一对多通信_基于Select模型

    TCP 一对多通信的程序(MFC 对话框程序),就是服务器端利用Select模型技术, 能同时接收多个客户端的消息, 其次, 服务器端还能将消息群发给所有已连接的客户端, 实现的基本思路 是使用Select模型的套接字集合...

    linux聊天室 tcp协议多并发模型

    实现登入 广播聊天的功能 tcp/ip 协议 select 函数运用

    多人聊天室

    多人聊天室 支持多人聊天,使用select模型

    广域网上聊天室多人聊天程序

    多人聊天程序, 广域网上聊天室,传送文件。

    SYC 聊天室程序源代码, 很不错的,跟大家共享下

    很不错的代码,对多线程、select异步模型都有应用,对菜鸟我来讲,一边能看懂

    局域网聊天室,内含源代码

    ....\局域网聊天室 ....\............\Chat_Client ....\............\...........\Chat_Client.aps ....\............\...........\Chat_Client.clw ....\............\...........\Chat_Client.cpp ....\.......

    局域网聊天室(vc++ 原码)

    这里是局域网聊天室程序的原码(VC++6 MFC)。 有比较多的中文注释, Server可以接很多的Client。...使用 Select 模型,多线程,自己封装的 Winsock API 类。 希望对初学Winsock的朋友有一点点的帮助。

    Python聊天室实例程序分享

    我们要实现的是简单的聊天室的例子,就是允许多个人同时一起聊天,每个人发送的消息所有人都能接收到,类似于 QQ 群的功能,而不是点对点的 QQ 好友之间的聊天。如下图: 我们要实现的有两部分: Chat Server:...

    局域网聊天室

    我大三写的 服务器端 和 客户端 使用select服务器模型 多线程技术 MFC自定义小时的发送 等等技术

    基于windows的socket编程

    socket网络编程,没有选用线程模式,而是选用的异步的select模型。windows下的WSASelect模型,基于消息传递机制,实现了一个服务器和客户端,聊天

    网络编程实用教程(第三版).zip

    8.1 select模型 210 8.2 WSAAsyncSelect异步I/O模型 212 8.3 WSAEventSelect事件选择模型 216 8.4 重叠I/O模型 221 8.4.1 重叠I/O模型的优点 221 8.4.2 重叠I/O模型的基本原理 221 8.4.3 重叠I/O模型的...

    linux网络编程

    udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 Linux网络编程...

    C++教程网《Linux网络编程》视频百度云地址

    udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址结构 UNIX域字节流回射客户/服务 UNIX域套接字编程注意点 22socket编程(十七) socketpair sendmsg/recvmsg UNIX域套接字传递描述符字 ...

Global site tag (gtag.js) - Google Analytics