服务器端对一个客户端来了就开启一个工作线程,最多可接受64个。

具体看代码:

#pragma once
#include <winsock.h>
#include <stdio.h> #pragma comment(lib, "ws2_32.lib") #define MaxClient 64 class MyTCPSocket
{
public:
MyTCPSocket(void);
~MyTCPSocket(void);
bool Init();
bool UnInit();
bool CreateSocket();
bool Bind(unsigned aPost,const char* aAdress);
bool Listen(int aBacklog=);
bool Connect(unsigned aPost,const char* aAdress);
bool Send(const char* aBuf);
bool Recv();
void Accept();
static DWORD WINAPI WorkerFun(PVOID aData); public:
SOCKET m_ClientSocket[MaxClient]; private:
SOCKET m_Socket; sockaddr_in m_SockClientaddrIn ;
HANDLE m_ClientHandle[MaxClient];
CRITICAL_SECTION m_CriticalSection;
DWORD m_Thread[MaxClient];
int m_TotClient;
};
#include "MyTCPSocket.h" struct Para
{
MyTCPSocket* m_pMyTCPSocket;
SOCKET m_CurSocket;
}; MyTCPSocket::MyTCPSocket(void)
:m_Socket(INVALID_SOCKET)
, m_TotClient(-)
{
InitializeCriticalSection(&m_CriticalSection);
} MyTCPSocket::~MyTCPSocket(void)
{
EnterCriticalSection(&m_CriticalSection);
for (int i =; i < m_TotClient;++i)
{
if (NULL != m_ClientHandle[i])
{
CloseHandle(m_ClientHandle[i]);
}
}
LeaveCriticalSection(&m_CriticalSection); DeleteCriticalSection(&m_CriticalSection);
} bool MyTCPSocket::Init()
{
int iResult;
WORD wVersionRequested;
WSADATA wsaData; wVersionRequested = MAKEWORD(, );
iResult = WSAStartup(wVersionRequested, &wsaData);
if (iResult != )
{
printf("WSAStartup failed with error: %d\n", iResult);
return false;
}
else
{
printf("WSAStartup succeeded!\n");
return true;
}
} bool MyTCPSocket::CreateSocket()
{
m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == m_Socket)
{
printf("INVALID_SOCKET\n");
return false;
}
printf("Create Socket(%d) successully.\n",m_Socket);
BOOL reuseaddr=TRUE;
setsockopt(m_Socket,SOL_SOCKET,SO_REUSEADDR,(const char*)&reuseaddr,sizeof(reuseaddr));
return true;
} bool MyTCPSocket::Bind(unsigned aPost,const char* aAdress)
{
struct sockaddr_in server_addr; // server address information
server_addr.sin_family = AF_INET; // host byte order
server_addr.sin_port = htons(aPost); // short, network byte order
server_addr.sin_addr.s_addr = inet_addr(aAdress); // automatically fill with my IP
memset(server_addr.sin_zero, '\0', sizeof(server_addr.sin_zero));
if (- == bind(m_Socket,(struct sockaddr *)&server_addr,sizeof(server_addr)))
{
printf("Bind Error.\n");
return false;
} int nRecvBuf = * ; //设置为32K
if (setsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int)) == -) {
perror("setsockopt");
exit();
}
return true;
} bool MyTCPSocket::Connect( unsigned aPost,const char* aAdress )
{
sockaddr_in lsockaddr_in;
lsockaddr_in.sin_family = AF_INET;
lsockaddr_in.sin_port = htons(aPost);
lsockaddr_in.sin_addr.s_addr = inet_addr(aAdress); if (- == connect(m_Socket,(struct sockaddr *)&lsockaddr_in,sizeof(lsockaddr_in)))
{
printf("Conenct Error.\n");
return false;
}
return true;
} bool MyTCPSocket::Listen( int aBacklog/*=5*/ )
{
if (- == listen(m_Socket,aBacklog))
{
printf("Listen Error.\n");
return false;
}
return true;
} bool MyTCPSocket::Send( const char* aBuf)
{
if (- == send(m_Socket,aBuf,strlen(aBuf)+,))
{
printf("Send Error.\n");
return false;
}
return true;
} bool MyTCPSocket::Recv()
{
//char lBuf[2048];
//int lLength = 0;
//lLength = recv(m_ClientSocket,lBuf,sizeof(lBuf),0);
//if (SOCKET_ERROR == lLength || 0 == lLength)
//{
// closesocket(m_ClientSocket);
// return false;
//}
//int lBegin = 0;
//int lEnd = 0;
//for (;lEnd < lLength;++lEnd)
//{
// if ('\0' == lBuf[lEnd])
// {
// char lData[1024];
// int lLen = lEnd-lBegin;
// memcpy(lData,lBuf+lBegin,lLen+1);
// printf("We successfully received %d byte: %s.\n", lLen, lData);
// lBegin = lEnd+1;
// }
//}
//if (lEnd < lLength)
//{
// char lData[1024];
// memcpy(lData,lBuf+lBegin,lEnd-lBegin);
// lData[lEnd] = '\0';
// printf("We successfully received %d byte: %s.\n", lData);
//}
//return true;
return true;
} bool MyTCPSocket::UnInit()
{
if (- == closesocket(m_Socket))
{
printf("Close Socket Error.\n");
return false;
}
printf("Close Socket(%d).\n",m_Socket);
return true;
} void MyTCPSocket::Accept()
{
while(true)
{
int lAddrLen = sizeof(m_SockClientaddrIn); if (m_TotClient == MaxClient-)
{
printf("Exceed max clients.\n");
break;
} EnterCriticalSection(&m_CriticalSection);
m_ClientSocket[++m_TotClient] = accept(m_Socket, (sockaddr*)&m_SockClientaddrIn,&lAddrLen); Para* lpPara = new Para;
lpPara->m_pMyTCPSocket = this;
lpPara->m_CurSocket = m_ClientSocket[m_TotClient];
LeaveCriticalSection(&m_CriticalSection); printf("We successfully got a connection from %s:%d.\n",
inet_ntoa(m_SockClientaddrIn.sin_addr), ntohs(m_SockClientaddrIn.sin_port)); m_ClientHandle[m_TotClient] = ::CreateThread(NULL, , WorkerFun,PVOID(lpPara), , &m_Thread[m_TotClient]); printf("Create WorkThread(%x) success.\n",m_Thread[m_TotClient]);
}
} DWORD WINAPI MyTCPSocket::WorkerFun( PVOID aData )
{
if (NULL == aData)
{
printf("Exit Thread.\n");
return ;
} Para* lpPara = (Para*)(aData);
MyTCPSocket* lTCPSocket = lpPara->m_pMyTCPSocket; if (lpPara->m_CurSocket == INVALID_SOCKET)
{
return ;
} while(true)
{
char lBuf[];
int lLength = ;
lLength = recv(lpPara->m_CurSocket,lBuf,sizeof(lBuf),);
if (SOCKET_ERROR == lLength || == lLength)
{
closesocket(lpPara->m_CurSocket);
delete lpPara;
printf("Exit Thread.\n");
return ;
}
int lBegin = ;
int lEnd = ;
for (;lEnd < lLength;++lEnd)
{
if ('\0' == lBuf[lEnd])
{
char lData[];
int lLen = lEnd-lBegin;
memcpy(lData,lBuf+lBegin,lLen+);
printf("We successfully received %d byte: %s.\n", lLen, lData);
lBegin = lEnd+;
}
}
if (lEnd < lLength)
{
char lData[];
memcpy(lData,lBuf+lBegin,lEnd-lBegin);
lData[lEnd] = '\0';
printf("We successfully received %d byte: %s.\n", lData);
}
} return ;
}

表示是很简陋的写法,肯定还是有问题的,同步的地方没怎么想清楚,测试代码可以看上一篇的介绍,好吧,今天暂时先写到这里,尼玛,公司写神码软件申请书,搓的一逼。

一个worker thread服务一个客户端的更多相关文章

  1. ROS学习笔记11-写一个简单的服务和客户端(C++版本)

    本文主要来源于:http://wiki.ros.org/ROS/Tutorials/WritingServiceClient%28c%2B%2B%29 写一个服务节点.在创建消息和服务中,我们创建了一 ...

  2. 曹工杂谈:花了两天时间,写了一个netty实现的http客户端,支持同步转异步和连接池(1)--核心逻辑讲解

    背景 先说下写这个的目的,其实是好奇,dubbo是怎么实现同步转异步的,然后了解到,其依赖了请求中携带的请求id来完成这个连接复用:然后我又发现,redisson这个redis客户端,底层也是用的ne ...

  3. Windows Azure入门教学系列 (三):创建第一个Worker Role程序

    在开始本教学之前,请确保你从Windows Azure 平台下载下载并安装了最新的Windows Azure开发工具.本教学使用Visual Studio 2010作为开发工具. 步骤一:创建解决方案 ...

  4. 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端

    接上文 多线程编程学习笔记——使用异步IO 二.   编写一个异步的HTTP服务器和客户端 本节展示了如何编写一个简单的异步HTTP服务器. 1.程序代码如下. using System; using ...

  5. 从零讲解搭建一个NIO消息服务端

    本文首发于本博客,如需转载,请申明出处. 假设 假设你已经了解并实现过了一些OIO消息服务端,并对异步消息服务端更有兴趣,那么本文或许能带你更好的入门,并了解JDK部分源码的关系流程,正如题目所说,笔 ...

  6. 服务注册中心之ZooKeeper系列(二) 实现一个简单微服务之间调用的例子

    上一篇文章简单介绍了ZooKeeper,讲了分布式中,每个微服务都会部署到多台服务器上,那服务之间的调用是怎么样的呢?如图: 1.集群A中的服务调用者如何发现集群B中的服务提供者呢? 2.集群A中的服 ...

  7. 如何设计一个异步Web服务——任务调度

    接上一篇<如何设计一个异步Web服务——接口部分> Application已经将任务信息发到了Service服务器中,接下来,Service服务器改如何对自身的资源进行合理分配以满足App ...

  8. WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]

    WCF入门教程(四)通过Host代码方式来承载服务 Posted on 2014-05-15 13:03 停留的风 阅读(7681) 评论(0) 编辑 收藏 WCF入门教程(四)通过Host代码方式来 ...

  9. eShopOnContainers 是一个基于微服务的.NET Core示例框架

    找到一个好的示例框架很难,但不是不可能.大多数是小型Todo风格的应用程序,通常基于SimpleCRUD.值得庆幸的是,Microsoft已经为eShopOnContainers创建了一个基于微服务的 ...

随机推荐

  1. map练习

    /* 编写程序统计并输出所读入的单词出现的次数 */ /* //代码一:---用map索引实现惊人的简练 #include <iostream> #include <map> ...

  2. capwap学习笔记——初识capwap(三)

    2.5.6 CAPWAP状态机详解 2.5.6.1 Start to Idle 这个状态变迁发生在设备初始化完成. ¢  WTP: 开启CAPWAP状态机.     ¢  AC:  开启CAPWAP状 ...

  3. WordPress 在function.php 文件中方法中the_XXX方法失效

    最近在使用WP给客户做一个企业网站,却出现从未遇到的问题. 事件是这样子的:我在function.php文件里写了一个根据分类ID获取文章的文章,因为该方法里的html元素是在多个页面共用的 但我在i ...

  4. linux不解压超大日志gz包直接查找特定内容

    gzip -dc myfile.gz | grep 'Exception' | more 或者 gzip -c myfile.gz | grep 'Exception' | more

  5. MATLAB中的集合运算

    matlab里关于集合运算和二进制数的运算的函数 intersect:集合交集ismember :是否集合中元素setdiff :集合差集setxor :集合异或(不在交集中的元素)union :两个 ...

  6. myeclipse集成jdk、tomcat8、maven、svn

    今天一个同学要回家了.回家之前叫我帮他配置一下开发环境.然后在家里面自己研究一下.敲下代码. 帮他配置好之后自己回来把这个过程写下来.别让自己把这个东西给忘了. myeclipse安装 myeclip ...

  7. oracle 复制表结构表数据

    create table Uc_t_Department3 as (select * from Uc_t_Department where 1=2);insert into Uc_t_Departme ...

  8. CSS外框高度自动适应

    当有浮动float时,最外框会不跟随内容的高度而高: 解决办法一:清除浮动  clear:both <!DOCTYPE html> <html xmlns="http:// ...

  9. js未分类

    jQuery设置透明 1.直接.fadeIn 淡入 .fadeOut 淡出 .fadeTo(时间,"透明度") 2.addClass只能控制淡入和淡出,不能控制其速度. filte ...

  10. 微信小程序 - radio/checkbox自定义组件

    更新 2019-01-26:首次发布 2019-01-27:增加默认取值选中radio/checkbox,checkbox需在onload取值 2019-01-28:增加radio取值不存在红色提示和 ...