/*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. 【转】修改 shellstyle.dll 权限

    原文网址:http://bbs.zol.com.cn/nbbbs/d160_147794.html 对于经常使用电脑的人来说,比如像最近的我,在晚上总觉得电脑资源管理器屏幕显示得太亮,即使我把电脑的亮 ...

  2. (总结)Linux下使用rsync最快速删除海量文件的方法

    昨天遇到了要在Linux下删除海量文件的情况,需要删除数十万个文件.这个是之前的程序写的日志,增长很快,而且没什么用.这个时候,我们常用的删除命令rm -fr * 就不好用了,因为要等待的时间太长.所 ...

  3. linux下删除所有.svn目录

    linux下删除所有.svn目录方法为    find . -type d -name ".svn"|xargs rm -rf    或者    find . -type d -i ...

  4. 答辩ppt

    目录:1.2.3.4 poct市场 荧光免疫技术(特点:灵敏性.可做仪器很小) 意义 国内外现状:万福.天宝 研究内容1.2.3. 一.意义与背景 二.内容(测量原理) 目标 三.仪器设计 1.基本测 ...

  5. JSBinding + SharpKit / 原理篇:内存管理与垃圾回收

    C# 和 JS 都有垃圾回收机制,需要保证 2 者能够分工协作. 类对象 类在C#中是引用类型.我们在 C# 中维护了2个map,保存 C# 对象和 JS 对象的一一对应关系. 举一个例子,看以下代码 ...

  6. 有关<table>的几个问题

    1)实现任意一行下边框的颜色设置: 单元格边距(表格填充)(cellpadding) -- 代表单元格外面的一个距离,用于隔开单元格与单元格空间 单元格间距(表格间距)(cellspacing) -- ...

  7. add to svn ignore disabled

    The problem is that the folder is already under version control. Here's how I fix this type of probl ...

  8. mac版photoshop滤镜库报错解法

    http://bbs.pcbeta.com/viewthread-1556878-1-1.html

  9. 【转】asp.net导出数据到Excel的三种方法

    来源:http://www.cnblogs.com/lishengpeng1982/archive/2008/04/03/1135490.html 原文出处:http://blog.csdn.net/ ...

  10. centos7通过yum安装mysql,并授权远程连接

    安装: CentOS 7的yum源中没有正常安装MySQL的mysql-sever文件,需要去官网上下载(通过安装mysql的yum容器,再通过yum安装mysql) 注:安装前,需要卸载所有的mar ...