先说一下Socket编程,普通C/S模型服务器端咋实现的。
1、打开网络库(校验版本号对不对)
2、创建服务器socket
3、bind,绑定IP地址类型,ip地址,端口类型在服务器socket。
4、设置监听(就是可以一直监听有谁来连接服务器)
5、创建客户端socket,接收连接。也就是accept函数去创建。
6、接收和发送信息。
但是这个模型有个缺点。在第五步的时候,如果没有人来访问就会直接阻塞掉服务器,或者多个客户端来,我们也不能接收第二个客户端信息。我们就没办法操作了,如果会多线程啥的可以多创建几个线程进行操作。但是这个不太科学,因为来连接服务器的并不是固定事件,所以创建几个都不太合适把。所以这个时候就有一个select模型冲出来了。
select模型,我个人理解,是把能接收到信息的,能发送信息的,和发生错误的分别放在一个数组中。需要用到的时候从其中取出来即可。流程如下如果不太懂。可能看看别的博客会好很多。
1、打开网络库(校验版本号对不对)
2、创建服务器socket
3、bind,绑定IP地址类型,ip地址,端口类型在服务器socket。
4、设置监听(就是可以一直监听有谁来连接服务器)
5、select模型--->不断从数组中取出获得的socket,如果是获得了服务器socket的话,说明有客户端上线了。这个时候用accept函数去接收连接(相比普通C/S模型这个就灵活很多了,不是傻等)。之后for一边数组,查看谁给我们服务器发送信息了,之后for一边可以发送信息的数组,看看我们能给谁发信息,for一边有错误的数组,看看哪个客户端出问题了。(这里有个错误是客户端强制下线,我测半天一直觉得,我关掉客户端应该属于正常下线,没想到这个是算错误)
还是看代码理解比较好:代码如下。
#include <iostream>
#include <WinSock2.h>
#include<string.h>
#include<stdlib.h>
#include<set>
#pragma comment(lib,"Ws2_32.lib")
bool checkSock(const FD_SET messSet,SOCKET Now) ///判断Now是否存在在
{
for (u_int i = 0; i < messSet.fd_count; i++)
{
if (Now == messSet.fd_array[i])
return true;
}
return false;
}
int main()
{
WORD wdVersion = MAKEWORD(2, 2);
WSADATA wdSockMeg;
///打开网络库
int StartWSAStartup = WSAStartup(wdVersion,&wdSockMeg);
if (StartWSAStartup != 0)//打开失败
{
switch (StartWSAStartup)
{
case WSASYSNOTREADY:
std::cout << "重启电脑试试,或者检查网络库" << std::endl;
break;
case WSAVERNOTSUPPORTED:
std::cout << "请更新网络库" << std::endl;
break;
case WSAEINPROGRESS:
std::cout << "请重新