博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个worker thread服务一个客户端
阅读量:5889 次
发布时间:2019-06-19

本文共 6849 字,大约阅读时间需要 22 分钟。

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

具体看代码:

#pragma once#include 
#include
#pragma comment(lib, "ws2_32.lib")#define MaxClient 64class MyTCPSocket{public: MyTCPSocket(void); ~MyTCPSocket(void); bool Init(); bool UnInit(); bool CreateSocket(); bool Bind(unsigned aPost,const char* aAdress); bool Listen(int aBacklog=5); 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(-1){ InitializeCriticalSection(&m_CriticalSection);}MyTCPSocket::~MyTCPSocket(void){ EnterCriticalSection(&m_CriticalSection); for (int i =0; 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(2, 2); iResult = WSAStartup(wVersionRequested, &wsaData); if (iResult != 0) { 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 (-1 == bind(m_Socket,(struct sockaddr *)&server_addr,sizeof(server_addr))) { printf("Bind Error.\n"); return false; } int nRecvBuf = 32 * 1024; //设置为32K if (setsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int)) == -1) { perror("setsockopt"); exit(1); } 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 (-1 == 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 (-1 == listen(m_Socket,aBacklog)) { printf("Listen Error.\n"); return false; } return true;}bool MyTCPSocket::Send( const char* aBuf){ if (-1 == send(m_Socket,aBuf,strlen(aBuf)+1,0)) { 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 (-1 == 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-1) { 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, 0, WorkerFun,PVOID(lpPara), 0, &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 0; } Para* lpPara = (Para*)(aData); MyTCPSocket* lTCPSocket = lpPara->m_pMyTCPSocket; if (lpPara->m_CurSocket == INVALID_SOCKET) { return 0; } while(true) { char lBuf[2048]; int lLength = 0; lLength = recv(lpPara->m_CurSocket,lBuf,sizeof(lBuf),0); if (SOCKET_ERROR == lLength || 0 == lLength) { closesocket(lpPara->m_CurSocket); delete lpPara; printf("Exit Thread.\n"); return 0; } 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 0;}

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

转载地址:http://hprix.baihongyu.com/

你可能感兴趣的文章
[转]Windows7 64bit下配置Apache+PHP+MySQL
查看>>
CentOS6.5 下在Nginx中添加SSL证书以支持HTTPS协议访问
查看>>
给trac的ticket添加提交时字段验证
查看>>
nodejs安装-配置
查看>>
Node.js学习-1
查看>>
今天你的应用崩溃了么?
查看>>
项目中的*签到*小功能!
查看>>
iOS 获取cell.accessoryView自定义视图以及点击事件
查看>>
java 考试试题
查看>>
[caffe(一)]使用caffe训练mnist数据集
查看>>
闭包,装饰器
查看>>
vs2013编译错误解决: _declspec(dllimport) 动态链接库
查看>>
这是一篇被河蟹了的博客
查看>>
一个两年Java的面试总结
查看>>
转:React Native之旅01-创建项目
查看>>
软件工程项目组Z.XML会议记录 2013/11/27
查看>>
科学计算库学习报告
查看>>
软件测试 -- 软件测试的风险主要体现在哪里
查看>>
修改App.config中的appSettings
查看>>
JQuery选择器总结
查看>>