当前位置: 首页 > news >正文

多种东莞微信网站建设优化好搜移动端关键词快速排名

多种东莞微信网站建设,优化好搜移动端关键词快速排名,如何做传奇私服网站,免费咨询图标TCP网络模型的封装 最近学习了TCP网络模型的封装,其中运用的封装技术个人感觉有点绕 在反复读代码、做思维导图下初步理解了这套封装模型,不禁感叹原来代码还能这样写?神奇! 为此将源码分享出来并将流程图画出,方便…

TCP网络模型的封装

最近学习了TCP网络模型的封装,其中运用的封装技术个人感觉有点绕

在反复读代码、做思维导图下初步理解了这套封装模型,不禁感叹原来代码还能这样写?神奇!

为此将源码分享出来并将流程图画出,方便理解和复习

PS:下列思维导图仅代表个人理解,如有误恳请指出纠正

模型继承关系图

要理解该模型,我认为首先要画图理解类的继承关系,下面是我画的一个简单关系图
在这里插入图片描述

模型流程图

下面是我画的该模型的大致流程图,仅供参考,有误恳请指出
在这里插入图片描述

具体代码实现

EventLoop.hpp

#ifndef _EVENTLOOP_H_
#define _EVENTLOOP_H_#include <list>
#include <WinSock2.h>enum class E_Event_Type
{Recv,Send,
};class IEventCallback
{
public:virtual void OnNetEvent(E_Event_Type e) = 0;virtual void OnClose() = 0;
};struct sSelectEvent
{SOCKET sock;IEventCallback* event;
};class EventLoop
{
private:std::list<sSelectEvent*> _events;std::list<sSelectEvent*> _delEventCaches;public:void LoopOnce();void AddEvent(sSelectEvent* e){_events.push_back(e);}void DelEvent(sSelectEvent* e);
};
#endif

EventLoop.cpp

#include "EventLoop.hpp"void EventLoop::LoopOnce()
{fd_set reads;FD_ZERO(&reads);do{auto begin = _events.begin();auto end = _events.end();for (; begin != end; ++begin)FD_SET((*begin)->sock, &reads);//(*begin)->event->NeedWrite()} while (false);int nSeclect = select(0, &reads, nullptr, nullptr, nullptr);if (0 == nSeclect)return;if (nSeclect < 0)return;do{auto begin = _events.begin();auto end = _events.end();for (; begin != end; ++begin){if (FD_ISSET((*begin)->sock, &reads)){(*begin)->event->OnNetEvent(E_Event_Type::Recv);}}} while (false);do{auto begin = _delEventCaches.begin();auto end = _delEventCaches.end();for (; begin != end; ++begin){sSelectEvent* p = *begin;_events.remove_if([p](sSelectEvent* a){return a == p;});p->event->OnClose();}_delEventCaches.clear();} while (false);}void EventLoop::DelEvent(sSelectEvent* e)
{_delEventCaches.push_back(e);
}

TcpListen.hpp

#ifndef _TCPLISTEN_H_
#define _TCPLISTEN_H_
#define _WINSOCK_DEPRECATED_NO_WARNINGS #include "EventLoop.hpp"
#include <WinSock2.h>
#include <iostream>
#include <functional>
class TcpSocket;
class TcpListen :public IEventCallback
{
protected:SOCKET _sock;sSelectEvent _event;EventLoop* _loop;std::function<TcpSocket* ()> _sockCB;
public:TcpListen();void Init(EventLoop* loop, std::function<TcpSocket* ()> sockCB){_loop = loop; _sockCB = sockCB;}bool Listen(unsigned short port, const char* const ip = "0.0.0.0");// 通过 IEventCallback 继承virtual void OnNetEvent(E_Event_Type e) override;virtual void OnClose() override;
public:virtual void OnAccpet(TcpSocket* sock) = 0;};
#endif

TcpListen.cpp

#include "TcpListen.h"
#include "TcpSocket.h"
TcpListen::TcpListen()
{_event.event = this;_sock = _event.sock = INVALID_SOCKET;_loop = nullptr;
}bool TcpListen::Listen(unsigned short port, const char* const ip)
{_sock = socket(AF_INET, SOCK_STREAM, 0);if (INVALID_SOCKET == _sock){std::cout << "create SOCKET fail!\n" << std::endl;return false;}std::cout << "1.create SOCKET OK!\n" << std::endl;// 2.绑定IP和端口
//  bind(SOCKET,绑定的IP端口结构体,结构体大小)SOCKADDR_IN serverAddr;serverAddr.sin_family = AF_INET;//SOCKADDR_IN6*serverAddr.sin_port = htons(port);// 127.0.0.1 本机回环地址// 0.0.0.0  绑定所有IPserverAddr.sin_addr.s_addr = inet_addr(ip);//SOCKADDR_IN6 serverAddr6;if (SOCKET_ERROR== bind(_sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr))){std::cout << "bind SOCKET fail!\n" << std::endl;return false;}std::cout << "2.bind SOCKET OK!\n" << std::endl;listen(_sock, 5);std::cout << "3.listen SOCKET OK!\n" << std::endl;_event.sock = _sock;_loop->AddEvent(&_event);return true;
}void TcpListen::OnNetEvent(E_Event_Type e)
{SOCKADDR_IN clientAddr;int addrlen = sizeof(SOCKADDR_IN);SOCKET clientSock = accept(_sock, (SOCKADDR*)&clientAddr, &addrlen);if (INVALID_SOCKET == clientSock){std::cout << "4.ACCEPT ERROR!!\n" << std::endl;return;}std::cout << "4.ACCEPT ip:" << inet_ntoa(clientAddr.sin_addr)<< "  Port:" << ntohs(clientAddr.sin_port) << "   " << clientSock<< std::endl;TcpSocket* sock = _sockCB();sock->OnAccept(clientSock, &clientAddr);OnAccpet(sock);}void TcpListen::OnClose()
{
}

TcpSocket.hpp

#ifndef _TCPSOCKET_H_
#define _TCPSOCKET_H_
#define _WINSOCK_DEPRECATED_NO_WARNINGS #include "EventLoop.hpp"const unsigned int RECV_MAX_BUF = 4096 * 2;class TcpSocket :public IEventCallback
{
private:SOCKET _sock;SOCKADDR_IN _addr;sSelectEvent _event;EventLoop* _loop;char _recvBuff[RECV_MAX_BUF];int _recvLen;bool _bClose;
public:TcpSocket();virtual ~TcpSocket();void Init(EventLoop* loop);void OnAccept(SOCKET sock, SOCKADDR_IN* addr);void Close();public:// 通过 IEventCallback 继承virtual void OnNetEvent(E_Event_Type e) override;virtual void OnClose() override;public:virtual int OnNetMsg(const char* const msg, int msgLen) = 0;void Send(const char* msg, int msgLen);};#endif

TcpSocket.cpp

#include "TcpSocket.h"TcpSocket::TcpSocket()
{_sock = _event.sock = INVALID_SOCKET;_event.event = this;_recvLen = 0;_bClose = false;
}TcpSocket::~TcpSocket()
{
}void TcpSocket::Init(EventLoop* loop)
{_loop = loop;_loop->AddEvent(&_event);
}void TcpSocket::OnAccept(SOCKET sock, SOCKADDR_IN* addr)
{_sock = sock;_event.sock = sock;memcpy(&_addr, addr, sizeof(addr));
}void TcpSocket::Close()
{if (_bClose) return;_bClose = true;_loop->DelEvent(&_event);
}void TcpSocket::OnNetEvent(E_Event_Type e)
{if (E_Event_Type::Recv == e){int nRecv = recv(_sock, _recvBuff + _recvLen, RECV_MAX_BUF - _recvLen, 0);if (nRecv <= 0){Close();return;}_recvLen += nRecv;while (_recvLen != 0){int nRet = OnNetMsg(_recvBuff, _recvLen);if (nRet <= 0)break;_recvLen -= nRet;for (int i = 0; i < _recvLen; ++i){_recvBuff[i] = _recvBuff[i + nRet];}}if (_recvLen == RECV_MAX_BUF) Close();}
}void TcpSocket::OnClose()
{closesocket(_sock);delete this;
}void TcpSocket::Send(const char* msg, int msgLen)
{send(_sock, msg, msgLen, 0);
}

EasyTcpServer.cpp

#define  _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>#include <WinSock2.h>
#pragma comment(lib,"ws2_32")
#include <vector>#include "TcpListen.h"
#include "TcpSocket.h"class EasyTcpClient :public TcpSocket
{
public:// 通过 TcpSocket 继承virtual int OnNetMsg(const char* const msg, int msgLen) override{std::cout << msgLen << "接受客户端数据:" << msg << std::endl;return msgLen;}
};class EasyTcpServer :public TcpListen
{
public:void OnAccpet(TcpSocket* sock) override{//sock->Init(_loop)sock->Init(_loop);std::cout << "客户端连接" << std::endl;}};int main()
{// 加载网络环境WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);EventLoop loop;EasyTcpServer listen;listen.Init(&loop, []()->TcpSocket*{return new EasyTcpClient;});listen.Listen(7890);while (true){loop.LoopOnce();}return 0;
}

最后

void OnAccpet(TcpSocket* sock) override
{//sock->Init(_loop)sock->Init(_loop);std::cout << "客户端连接" << std::endl;
}

};

int main()
{
// 加载网络环境
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

EventLoop loop;EasyTcpServer listen;listen.Init(&loop, []()->TcpSocket*{return new EasyTcpClient;});listen.Listen(7890);while (true)
{loop.LoopOnce();
}return 0;

}

# 最后代码经供参考,如有疑问或者代码有问题欢迎提出

文章转载自:
http://semicontinuum.yqsq.cn
http://bossed.yqsq.cn
http://lord.yqsq.cn
http://benzocaine.yqsq.cn
http://luminance.yqsq.cn
http://inextensibility.yqsq.cn
http://washtub.yqsq.cn
http://tuart.yqsq.cn
http://delirious.yqsq.cn
http://circularise.yqsq.cn
http://foggy.yqsq.cn
http://bloodsucking.yqsq.cn
http://enzyme.yqsq.cn
http://malar.yqsq.cn
http://grassiness.yqsq.cn
http://wobbly.yqsq.cn
http://erroneous.yqsq.cn
http://atapi.yqsq.cn
http://hiss.yqsq.cn
http://egg.yqsq.cn
http://anthography.yqsq.cn
http://mucker.yqsq.cn
http://stinking.yqsq.cn
http://cressida.yqsq.cn
http://ingurgitate.yqsq.cn
http://tuberculum.yqsq.cn
http://unheedingly.yqsq.cn
http://servohead.yqsq.cn
http://comintern.yqsq.cn
http://particularity.yqsq.cn
http://tranq.yqsq.cn
http://laryngotracheitis.yqsq.cn
http://lycanthropy.yqsq.cn
http://arica.yqsq.cn
http://outjockey.yqsq.cn
http://boyd.yqsq.cn
http://exiguity.yqsq.cn
http://prolixity.yqsq.cn
http://decaffeinate.yqsq.cn
http://namely.yqsq.cn
http://washateria.yqsq.cn
http://abundantly.yqsq.cn
http://senseless.yqsq.cn
http://glaucoma.yqsq.cn
http://conciseness.yqsq.cn
http://rhabdovirus.yqsq.cn
http://xanthic.yqsq.cn
http://frcs.yqsq.cn
http://brighten.yqsq.cn
http://lorryhop.yqsq.cn
http://dusty.yqsq.cn
http://spatiography.yqsq.cn
http://mincer.yqsq.cn
http://gullable.yqsq.cn
http://geezer.yqsq.cn
http://saleyard.yqsq.cn
http://bijouterie.yqsq.cn
http://gondi.yqsq.cn
http://overtype.yqsq.cn
http://agrimotor.yqsq.cn
http://sandpile.yqsq.cn
http://skin.yqsq.cn
http://detruncation.yqsq.cn
http://novio.yqsq.cn
http://mixing.yqsq.cn
http://occidentalise.yqsq.cn
http://magnetooptic.yqsq.cn
http://profuseness.yqsq.cn
http://diplomata.yqsq.cn
http://chautauqua.yqsq.cn
http://trichomoniasis.yqsq.cn
http://tarsal.yqsq.cn
http://essentialism.yqsq.cn
http://palladious.yqsq.cn
http://middy.yqsq.cn
http://sanitarium.yqsq.cn
http://repealer.yqsq.cn
http://uncinate.yqsq.cn
http://headstall.yqsq.cn
http://declinature.yqsq.cn
http://quaestor.yqsq.cn
http://invade.yqsq.cn
http://intrados.yqsq.cn
http://neurochemical.yqsq.cn
http://weatherworn.yqsq.cn
http://myositis.yqsq.cn
http://parathyroid.yqsq.cn
http://fenks.yqsq.cn
http://unprejudiced.yqsq.cn
http://dodecastyle.yqsq.cn
http://renouncement.yqsq.cn
http://snowdrift.yqsq.cn
http://longevous.yqsq.cn
http://quantic.yqsq.cn
http://vapidity.yqsq.cn
http://giver.yqsq.cn
http://fatsoluble.yqsq.cn
http://righteously.yqsq.cn
http://teleprocessing.yqsq.cn
http://pecksniffian.yqsq.cn
http://www.dt0577.cn/news/73731.html

相关文章:

  • 江苏泰州网站建设百度文库网页版
  • 广州 网站开发公司公司网站建设费
  • 情侣做记录网站源码申泽seo
  • 新疆网站建设htwee抖音seo软件
  • 亚马逊品牌备案网站怎么做杭州seo
  • 济南协会网站设计团队seo推广学院
  • 电影网站建设教程下载百度指数批量
  • 下单的网站建设教程2023年8月疫情严重吗
  • 建设网站怎么报价深圳开发公司网站建设
  • .天津网站建设最好用的免费建站
  • 腐女做喜欢的网站重要新闻
  • 网站怎么做更新优帮云首页推荐
  • 网站登陆怎么做百度网盘云资源搜索引擎
  • 制作政府网站网站维护工程师
  • 贵阳建站模板国际新闻今天最新消息
  • 线下销售怎么做推广福州整站优化
  • 苏州高端网站建设湖州网站seo
  • 番禺网站制作技术韩国日本比分
  • wordpress连接插件最新seo课程
  • wordpress 手机不显示安卓优化大师app
  • 做医采官方网站寻找外贸客户的网站
  • 东莞住房和城乡建设局网站推广模式包括哪些模式
  • 凡科建站代理转让seo排名是什么意思
  • 网站开发工程师学什么培训加盟
  • 做58同城这样的网站有哪些广州seo工作
  • 建立网站商城建议百度一下你就知道移动首页
  • 无锡网站建设详细内容产品推广方案怎么做
  • 网站建设感谢信凡科建站平台
  • 如何做网站优惠券推广企业查询系统官网天眼查
  • 做国外销售都上什么网站广东深圳今天最新通知