/*Author:  wainiwann

*Source: 博客园 http://www.cnblogs.com/wainiwann

*Remarks:  转载请说明出处!!!

*/

感觉很不错,可以学习一下。

socket下server端支持多客户端并发访问简单实现

server端开启之后始终有两个线程在处理连接请求,一个是只负责客户端的请求连接的(这里是只针对TCP协议),当客户端connect的时候 记录当前客户端连接存放到数据组中当中,而这个数组声明为全局成员,其实在线程内处理外部成员的话,也没必要非要用静态或者全局成员,今天听经理说也可以 在创建该线程时,把某类的this指针传递过去,同样好像也可以访问public成员的,具体行不行,还没试不过真的是不错的方法。要知道很多在项目很避 讳使用全局的东西,甚至有的公司直接不让使用全局的东西。这里扯的有点远了。

另外一个同步允许的线程就是对accept记录的数组进行操作,依次处理各个客户端请求通信和状态监控等,当数组内socket成员不为空时记录当前索引然后在create发送或者获取线程处理函数并发响应多个客户端的连接请求通信

加载套接字库:

BOOL TcpServer::InitSocket()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( , );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != )
{
return FALSE;
} if ( LOBYTE( wsaData.wVersion ) != || HIBYTE( wsaData.wVersion ) != )
{
WSACleanup( );
return FALSE;
} //创建套接字
//SOCKET m_socket=socket(AF_INET,SOCK_STREAM,0); return TRUE;
}

开启执行Accept线程处理函数:

BOOL TcpServer::SatartServer()
{
//创建线程
HANDLE hThread = CreateThread(NULL,,ThreadProc_Accept,NULL,,NULL);
//关闭该接收线程句柄,释放引用计数
CloseHandle(hThread); return TRUE;
}

线程处理函数:

DWORD WINAPI TcpServer::ThreadProc_Accept(LPVOID lpParameter)
{
int len = sizeof(SOCKADDR);
int err;
m_socket=socket(AF_INET,SOCK_STREAM,);
if (m_socket == INVALID_SOCKET)
{
AfxMessageBox(_T("套接字创建失败!"));
return FALSE;
} SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(); err = bind(m_socket,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); //绑定本地端口
if (err==SOCKET_ERROR)
{
closesocket(m_socket);
AfxMessageBox(_T("绑定失败!"));
return FALSE;
}
listen(m_socket,);//开启监听 //创建线程
HANDLE hThread = CreateThread(NULL,,ThreadProc_Select,NULL,,NULL);
//关闭该接收线程句柄,释放引用计数
CloseHandle(hThread); while (TRUE)
{
m_CliSocketArr[m_ToolConn++] = accept(m_socket,(SOCKADDR*)&addrSrv,&len);
}
return ;
}

同时在该线程函数内创建处理客户端数组的线程处理函数:

DWORD WINAPI TcpServer::ThreadProc_Select(LPVOID lpParameter)
{
int recvflag=; fd_set fdread; //读集fdread
int ret; //查看某个套接字的状态
struct timeval tv = {,}; //实例化timeval变量 while (TRUE)
{
//判断当前连接数是否为 0
if (m_ToolConn == )
{
Sleep();
continue;
} FD_ZERO(&fdread);
for (int i = ;i < m_ToolConn;i++)
{
FD_SET(m_CliSocketArr[i],&fdread);
}
ret = select(,&fdread,NULL,NULL,&tv);
if (ret == )
{
continue;
}
for (int i =;i<m_ToolConn;i++)
{
if (FD_ISSET(m_CliSocketArr[i],&fdread))
{
ret = recv(m_CliSocketArr[i],(char*)&recvflag,sizeof(int)+,);
if (ret == || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
{
closesocket(m_CliSocketArr[i]);
if (i < m_ToolConn-)
{
m_CliSocketArr[i] = m_CliSocketArr[--m_ToolConn];
}else
{
--m_ToolConn;
} }else
{
INDEX * inx = new INDEX;
inx->flag = recvflag;
inx->index = i; //创建线程
HANDLE hThread = CreateThread(NULL,,ThreadProc_Response,(LPVOID)inx,,NULL);
//关闭该接收线程句柄,释放引用计数
CloseHandle(hThread); }
}//if
}//for
}//while return ;
}

下面就是一次创建线程并发处理客户端请求线程处理函数:

DWORD WINAPI TcpServer::ThreadProc_Response(LPVOID lpParameter)
{
int ix = ((INDEX*)lpParameter)->index;
int flag = ((INDEX*)lpParameter)->flag; delete lpParameter; if (flag == )
{
//.............................
unsigned char sendBuffer[] = {'a'};
send(m_CliSocketArr[ix],(char*)sendBuffer,sizeof(sendBuffer)+,);
} return ;
}

线程处理函数在定义时,要设置为static或者是全局函数。

[转载]socket下server端支持多客户端并发访问简单实现的更多相关文章

  1. 在socket的server端处理client端发来的数据

    一.楔子 最近做了一个需求遇到一个坑,归结成一个小问题,其实就是在socket的server端处理client端发来的数据的问题,现将这个问题总结一下,本文将数据在server端以字典的形式存储. 另 ...

  2. Linux下的C Socket编程 -- server端的简单示例

    Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...

  3. Linux下的C Socket编程 -- server端的继续研究

    Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...

  4. [转载]linux下配置mariadb支持中文

    转载网址:http://www.cnblogs.com/vingi/articles/4302330.html 修改/etc/mysql/my.cnfOn MySQL 5.5 I have in my ...

  5. 上机题目(0基础)- Java网络操作-Socket实现client和server端通信二(Java)

    上一节实现了client像server端发送请求.本节将实现server端向client回传信息.实现原理非常easy,在原来的基础上.在server端实现输出流,在client实现输入流就可以,详细 ...

  6. 从零开始学习Node.js例子四 多页面实现数学运算 续二(client端和server端)

    1.server端 支持数学运算的服务器,服务器的返回结果用json对象表示. math-server.js //通过监听3000端口使其作为Math Wizard的后台程序 var math = r ...

  7. 一次http请求,谁会先断开TCP连接?什么情况下客户端先断,什么情况下服务端先断?

    我们有2台内部http服务(nginx): 201:这台服务器部署的服务是account.api.91160.com,这个服务是供前端页面调用: 202:这台服务器部署的服务是hdbs.api.911 ...

  8. [转载] Linux下高并发socket最大连接数所受的各种限制

    原文: http://mp.weixin.qq.com/s?__biz=MzAwNjMxNjQzNA==&mid=207772333&idx=1&sn=cfc8aadb422f ...

  9. java socket实现服务端,客户端简单网络通信。Chat

    之前写的实现简单网络通信的代码,有一些严重bug.后面详细写. 根据上次的代码,主要增加了用户注册,登录页面,以及实现了实时显示当前在登录状态的人数.并解决一些上次未发现的bug.(主要功能代码参见之 ...

随机推荐

  1. [PA2014] [BZOJ 3709]~[BZOJ 3719] 合集

    今天起尝试做套题喵~ (当然是因为被最大流的题目弄得恶心死了) 一共是 10 道题一道一道做 预计 3~4 内做完 尽情期待 [BZOJ 3709]Bohater 一眼就能感受到贪心的气息 因为很直观 ...

  2. Git-仓库迁移

    如果你想从别的 Git 托管服务那里复制一份源代码到新的 Git 托管服务器上的话,可以通过以下步骤来操作.1). 从原地址克隆一份裸版本库,比如原本托管于 GitHub. git clone --b ...

  3. 用margin还是用padding

    用margin还是用padding这个问题是每个学习CSS进阶时的必经之路. 分类: Html/CSS | 转载请注明: 出自 海玉的博客 本文地址: http://www.hicss.net/use ...

  4. OCR文字识别软件许可文件被误删了怎么办

    使用任何一款软件,都会有误操作的情况发生,比如清理文件时一不小心删除了许可文件,对于ABBYY FineReader 12这样一款OCR文字识别软件,因失误错误删除了许可文件该怎么办呢?今天就来给大家 ...

  5. 怎么在OCR文字识别软件中安装和启动 OCR文字识别软件 Hot Folder

    默认情况下,ABBYY Hot Folder 会与 ABBYY FineReader 12 一起安装到计算机中.(关于ABBYY FineReader 12请参考ABBYY FineReader 12 ...

  6. Js中的window.parent ,window.top,window.self ,window.openner详解

    在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe),self是当前窗口, opener是用open方法 ...

  7. 虚拟化之vmware虚拟机扩容与克隆

    前提条件: 1.在新建虚拟机的时候创建磁盘如下图,之后这个磁盘就可以在虚拟机关机状态下动态扩展大小,否则只能通过添加另外一块硬盘的方式来扩容.

  8. MongoDB权限管理之用户名和密码的操作

    MongoDB默认是不需要输入用户名和密码,客户就可以登录的.但是出于安全性的考虑,我们还是要为其设置用户名和密码.本文主要介绍的是MongoDB权限管理之用户名和密码的操作,希望能对您有所帮助. 本 ...

  9. SVN的分支、主干合并的使用说明

    EBAPP代码SVN服务器地址:http://scm.jrj.cn/webapp/ 使用右键菜单中SVN的二级菜单Repo-Broswer查看SVN服务器目录结构 目录结构如下: 名称及功能说明: T ...

  10. C# XML与Json之间相互转换实例详解

    对于这转换其实很简单,其中最重要的就是先要引用类库.可以到官网进行下载引用http://json.codeplex.com. XML转换为Json字符串 string xml = @"< ...