# chenyue **Repository Path**: wxl200219/chenyue ## Basic Information - **Project Name**: chenyue - **Description**: “基于完成端口的通信平台”: 框架借鉴Mina实现过滤链,IOHandler,IOBuffer,Idle,断包,编解码器等,底层用IOCP封装。借鉴tcp编号机制,实现内存池提升性能,利用IOCP底层线程管理设计线程模型挖掘性能,线程设计为n+1,n个处理数据,一个线程负责检查idle、平台安全退出等。 使用平台的用户只需简单配置自己的编解码器、责任链、和业务代码,就可以开发出属于自己的功能模块。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 6 - **Forks**: 0 - **Created**: 2022-02-06 - **Last Updated**: 2023-11-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # "基于IOCP的网络通信平台" ## 平台简介 看了Java-Mina的设计模式之后觉得非常妙,但是在C语言的环境下却没有一套这样的框架,找老师商量想法也得到老师的支持,于是利用课余时间开始制作。使用框架只需简单配置自己的编解码器、责任链、和业务代码,就可以开发出属于自己的功能模块。 * 代码的注释和自己的调试痕迹都没有删,看起来没那么清爽,但是目前是可用的 * 平台还在持续更新中,大家可以找我交流意见(备注项目名称) * QQ:`156946462` 微信: `wxl17671005416` ## 基础使用样例 平台源码包含使用样例,所有带MY开头的文件是样例文件,为框架非必须的文件,可以更改和删除 --- #### 1.主函数的配置 ```C //main.cpp文件 #include #include "NioSocketAcceptor.h" using namespace std; #include "MydeCodeFilterChain1.h" #include "MyIohander.h" int main(){ //1、创建入口对象 IoAcceptor *acceptor = new NioSocketAcceptor(8); //2、配置自己的编解码器 acceptor->addFilterChainLast(new MydeCodeFilterChain1("mydecodechain")); //3、配置自己的业务类 acceptor->setHandler(new MyIohander()); //4、绑定port和ip(默认开始运行) acceptor->bind("12345","192.168.28.106"); return 0; } ``` --- #### 2.定义的协议格式 ```c //MyMessage.h #ifndef CHENYUENEW_MYMESSAGE_H #define CHENYUENEW_MYMESSAGE_H #include "Message.h" class MyMessage : public Message{ public: MyMessage(){ this->headLen = 26; } //指定包的首部长度 int packLen; //4 BYTE flag; //1 unsigned short len; //2 char idFrom[10]; //9 char idTo[10]; //9 char keep[3]; //3 char type; //2 unsigned short length; //4 std::string contect; }; #endif //CHENYUENEW_MYMESSAGE_H ``` --- #### 3.编解码器编写 ```c //MydeCodeFilterChain1.h文件 class MydeCodeFilterChain1 : public ProtocolCodecFactory{ public: MydeCodeFilterChain1(const std::string& str): ProtocolCodecFactory(str){}; Message *deCode(Session *pSession, IoBuffer *ioBuffer) override; }; ``` ```c //MydeCodeFilterChain1.cpp文件 MyMessage *message = new MyMessage(); if(ioBuffer->getBufferLen() <= message->headLen) return NULL; //开始解包,其使用方式类似java中的IOBuffter ioBuffer->filp(); ioBuffer->getBuffer((BYTE*)message->idFrom,10); ioBuffer->getBuffer((BYTE*)message->idTo,10); ioBuffer->getBuffer((BYTE*)message->keep,3); message->type = ioBuffer->getByte(); message->length = ioBuffer->getShort(); message->contect = ioBuffer->getString(pSession->packetLen - 2 - message->headLen); ioBuffer->compact(); return message; ``` --- #### 4.编写的业务类 ```c //MyIohander.h文件 class MyIohander: public IoHandler{ public: void sessionCreated(Session *session) override; void sessionIdle(Session var1, IdleStatus var2) override; void sessionClosed(Session *session) override; void messageSent(Session *session, Message *message) override; void messageReceived(Session *session, Message *message) override; }; ``` ```c //MyIohander.cpp文件 #include #include "MyIohander.h" #include "MyMessage.h" void MyIohander::sessionCreated(Session *session) {} void MyIohander::sessionClosed(Session *session) {} void MyIohander::messageSent(Session *session, Message *message) {} void MyIohander::messageReceived(Session *session, Message *message) { if(NULL == message) return; MyMessage * myMessage = (MyMessage *)message; std::cout<<"(Iohander:)"<idFrom<idTo<type<contect< #include #include #include #pragma comment(lib,"Ws2_32.lib") using namespace std; //包首结构(数据长度,自己的id,目的id和,保留字段,数据类型,包长度) typedef struct Packet { unsigned short len; char idFrom[10]; char idTo[10]; char keep[3]; char type; short length; }PACKET_HEAD; #define CMD_MSG 1 #define CMD_FACE 2 //传输文本的包结构 typedef struct Packet_Text :PACKET_HEAD { char data[1000]; }PACKET_TEXT; //传输表情的包结构 typedef struct Packet_Face :PACKET_HEAD { char face; }PACKET_FACE; int main() { //打开网络库 WORD wdVersion = MAKEWORD(2,2); WSADATA wsaData; if (0 != WSAStartup(wdVersion,&wsaData)) { printf("WSAStartup fail!" ); return -1; } //校验版本 if (2 != HIBYTE(wsaData.wHighVersion) || 2 != LOBYTE(wsaData.wVersion)) { printf("Version fail!"); WSACleanup();//关闭库 return -1; } //创建一个SOCKET 监听 SOCKET socketUser = socket(AF_INET,SOCK_STREAM,0); //这个就是i产生错误了h if (INVALID_SOCKET == socketUser) { printf("socket fail!"); WSACleanup();//关闭库 return -1; } //初始化服务端的地址, 那么这个 是配置的服务器端的,一定要跟服务器一样,不然就练补上了 SOCKADDR_IN sockAddress; sockAddress.sin_family = AF_INET; //IPv4的协议 sockAddress.sin_addr.s_addr = inet_addr("192.168.28.106"); //服务器地址 sockAddress.sin_port = htons(12345); //服务器的端口 //客户端主动连接服务端 这个函数就是链接函数 int nFlag = connect(socketUser,(struct sockaddr*)&sockAddress,sizeof(sockAddress)); if (SOCKET_ERROR == nFlag) { printf("connect fail!" ); closesocket(socketUser);//关闭客户Socket WSACleanup();//关闭库 return -1; } //发送消息给服务器 while(1) { char szSendData[110]; PACKET_TEXT pPacket; memset((void*)&pPacket, '\0', 28); memcpy(pPacket.idFrom, "031942014", 9); memcpy(pPacket.idTo, "031942014", 9); memcpy(pPacket.keep, "000", 3); //memcpy(&pPacket.type, "1", 1); pPacket.type = 1; printf("Input Something : "); scanf("%s", szSendData); memcpy(pPacket.data, szSendData, sizeof(szSendData)); pPacket.data[strlen(szSendData)] = '\0'; //加上字符串结束标记 //packet.cmd = CMD_MSG; cout << strlen(szSendData); pPacket.len =(strlen(szSendData) + 1 + 28); pPacket.length = (short)(strlen(szSendData) + 1 + 26 ); //发送数据, 这个的话,跟服务器端的一样! if (SOCKET_ERROR == send(socketUser, (char *)&pPacket, pPacket.len,0)) { printf("send fail!" ); closesocket(socketUser);//关闭客户Socket WSACleanup();//关闭库 return -1; } } closesocket(socketUser);//关闭socket WSACleanup();//关闭网络库 system("pause"); return 0; } ```