服务器端对一个客户端来了就开启一个工作线程,最多可接受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. capwap学习笔记——capwap的前世今生(转)

    公司要做AP和AC,从今天开始学习capwap. 1 capwap的前世今生 1.1 胖AP.瘦AP.AC 传统的WLAN网络都是为企业或家庭内少量移动用户的接入而组建的.因此,只需要一个无线路由器就 ...

  2. (转)真正的中国天气api接口xml,json(求加精) ...

      我只想说现在网上那几个api完全坑爹有木有??? 官方的申请不来有木有,还有收费有木有?? 咱这种菜鸟只能用免费的了!!!! http://m.weather.com.cn/data/101110 ...

  3. Sql Server重复数据删除

    --在sql2005下可以 ,sql2000不可以 create  table tb(id int,name varchar(4))insert tb select 1,'aa'union all s ...

  4. [Canvas]RPG游戏雏形 (地图加载,英雄出现并移动)

    源码请点此下载并用浏览器打开index.html观看 图例: 代码: <!DOCTYPE html> <html lang="utf-8"> <met ...

  5. BAT,你好!字幕组,再见!——也许要跟美剧说再见了~

    对于美剧迷来说,上周的星期六(2014 年11 月 22 日)是黑色的一天. 11 月 22 日,人人影视暂时关站,并发布公告称网站正在清理内容.虽然这不是人人影视第一次关站清理,而且人人影视还给出提 ...

  6. 百度搜索URL参数

    http://www.baidu.com/s?wd=关键字wd(Keyword):查询的关键词:http://www.baidu.com/s?wd=关键字&cl=3cl(Class):搜索类型 ...

  7. [网摘][医学影像] DICOM 和 NIFTI 基础知识与区别

    查找DICOM基础知识时,看到这篇文章里面写了一些关于使用深度学习进行医疗影像分析:文件格式篇.下文摘自:https://www.jiqizhixin.com/articles/2017-07-31 ...

  8. git ingore添加忽略文件无较的解决方法

    一.启动Git Bash并切换到项目目录下 二.执行下列语句: git rm -r --cached . git add . git commit -m 'update .gitignore' 三.O ...

  9. SourceTree安装教程

    一.安装Git 链接: http://pan.baidu.com/s/1mh7rICK 密码: 48dj 二.安装SourceTree 链接: http://pan.baidu.com/s/1skWk ...

  10. java 中文及特殊字符校验

      java 中文及特殊字符校验 CreateTime--2017年8月25日16:54:50 Author:Marydon 一.参考链接 http://blog.csdn.net/imduan/ar ...