服务器端对一个客户端来了就开启一个工作线程,最多可接受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. Spring Boot集成MyBatis开发Web项目

    1.Maven构建Spring Boot 创建Maven Web工程,引入spring-boot-starter-parent依赖 <project xmlns="http://mav ...

  2. nodejs pipe实现大文件拷贝

    原文: http://nqdeng.github.io/7-days-nodejs/ --------------------------------------------------------- ...

  3. Maven镜像收集

    本贴主要收集国内国外速度比较快的maven镜像,OSC的MAVEN已经关闭了 0.阿里Maven镜像 setting.xml https://github.com/ae6623/Zebra/blob/ ...

  4. IDEA 不能显示项目里的文件结构

    方法一: 关闭IDEA, 然后删除项目文件夹下的.idea文件夹 重新用IDEA工具打开项目 方法二: 菜单:File -> Invalidate Caches / Restart

  5. [Git] Undo a commit that has already been pushed to the remote repository

    If we pushed our changes already to the remote repository we have to pay attention to not change the ...

  6. ASP入门(六)-Response对象

    Response对象可以从服务器向用户发送输出的结果. Response几种常用方法 方法 描述 BinaryWrite 向浏览器输出二进制的内容 Clear 清除已经缓冲的HTML输出 End 停止 ...

  7. Asp.NET websocket,Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室)

    ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及 ...

  8. 算法基础:删除字符串中出现次数最少的字符(Golang实现)

    描写叙述: 实现删除字符串中出现次数最少的字符.若多个字符出现次数一样,则都删除.输出删除这些单词后的字符串. 字符串中其他字符保持原来的顺序. 输入: 字符串仅仅包括小写英文字母, 不考虑非法输入, ...

  9. Android:安装时提示:INSTALL_FAILED_INSUFFICIENT_STORAGE

    在将程序发布到手机上时提示该错误: INSTALL_FAILED_INSUFFICIENT_STORAGE 解决方法: 1. adb shell 2. #df # df df Filesystem   ...

  10. 在CentOS7(虚拟机)下通过源码安装Postgresql10以及基本配置

    操作系统:CentOS7 安装文件:postgresql-10.0.tar.gz 系统环境:gcc.Python 1:源码安装 [postgres@localhost ~]# tar zxvf pos ...