diff --git a/Net.xcodeproj/project.pbxproj b/Net.xcodeproj/project.pbxproj index 27c71b3..1cab8af 100644 --- a/Net.xcodeproj/project.pbxproj +++ b/Net.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 926E0965220B17FA00AD5D5B /* client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 926E0964220B17FA00AD5D5B /* client.cpp */; }; 9277A16021FD725F009C5F11 /* md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15421FD725F009C5F11 /* md5.cpp */; }; 9277A16121FD725F009C5F11 /* cproj_cpt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15521FD725F009C5F11 /* cproj_cpt.cpp */; }; 9277A16221FD725F009C5F11 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15621FD725F009C5F11 /* main.cpp */; }; @@ -39,6 +40,7 @@ /* Begin PBXFileReference section */ 9221D9EB21EA5142007310A7 /* Net */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Net; sourceTree = BUILT_PRODUCTS_DIR; }; 926E09632209D9D300AD5D5B /* instruct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = instruct.h; path = include/instruct.h; sourceTree = ""; }; + 926E0964220B17FA00AD5D5B /* client.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = client.cpp; path = src/client.cpp; sourceTree = ""; }; 9277A14621FD7246009C5F11 /* cmap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cmap.h; path = include/cmap.h; sourceTree = ""; }; 9277A14721FD7246009C5F11 /* server.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = server.h; path = include/server.h; sourceTree = ""; }; 9277A14821FD7246009C5F11 /* net.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = net.h; path = include/net.h; sourceTree = ""; }; @@ -153,6 +155,7 @@ 9277A15321FD725F009C5F11 /* socket.cpp */, 9277A18A220076EE009C5F11 /* sql.cpp */, 9277A18F220079DB009C5F11 /* cproj_proj.cpp */, + 926E0964220B17FA00AD5D5B /* client.cpp */, ); name = src; sourceTree = ""; @@ -235,6 +238,7 @@ 92C34C272205C63A00AB38D3 /* server.cpp in Sources */, 92C34C282205C94600AB38D3 /* addr.cpp in Sources */, 92C34C292205C95F00AB38D3 /* socket.cpp in Sources */, + 926E0965220B17FA00AD5D5B /* client.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/include/server.h b/include/server.h index 63ddff7..3620741 100644 --- a/include/server.h +++ b/include/server.h @@ -30,7 +30,7 @@ struct compute_result{ //请求数据包 struct request { - rng::rng64 r_id = 0; + rng::rng64 r_id; string type; string data; uint32_t recv_port; @@ -38,11 +38,6 @@ struct request { request(); }; -//请求监听管理结构 -struct request_listener{ - -} - struct respond { rng::rng64 r_id; string type; @@ -87,6 +82,17 @@ public: } }; +//请求监听管理结构 +struct request_listener{ + void (*callback)(respond *); + request *p_req; + uint32_t timeout; + uint32_t clicks; + raw_data trwd; + bool active; + ~request_listener(); +}; + struct server_info{ string tag; string name; @@ -173,10 +179,25 @@ public: }; class Client{ - list req_lst; +// 请求监听列表 + list req_lst; +// 回复处理列表 + list res_lst; +// 请求监听端口 uint32_t listen_port; - - + SocketUDPServer socket; + SocketUDPClient send_socket; +public: +// 构造函数(send_port指的是发送的目标端口) + Client(int port = 9050, string send_ip = "127.0.0.1",int send_port = 9049); +// 处理请求监听 + void ProcessRequestListener(void); +// 新的请求 + void NewRequest(request **ppreq,string send_ip,int send_port,string type, string data); +// 新的请求监听 + void NewRequestListener(request *preq, int timeout, void (*callback)(respond *)); +// 友元回复接受守护进程 + friend void *clientRespondDeamon(void *); }; //设置服务器守护线程的时钟 @@ -194,4 +215,12 @@ void *requestProcessorDeamonForSquare(void *pvcti); //服务器发送数据包守护线程 void *sendPacketProcessorDeamonForSquare(void *pvcti); + +//设置客户端请求监听守护时钟 +void setClientClock(Client *pclient,int clicks); +//客户端请求监听守护线程 +void *clientRequestDeamon(void *pvclt); +//客户端回复接收守护线程 +void *clientRespondDeamon(void *pvclt); + #endif /* server_h */ diff --git a/src/client.cpp b/src/client.cpp index 81509f9..5828f0a 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1,48 +1,169 @@ // -// main.cpp -// Netc +// client.cpp +// Net // -// Created by 胡一兵 on 2019/1/13. +// Created by 胡一兵 on 2019/2/6. // Copyright © 2019年 Bakantu. All rights reserved. // -#include "instruct.h" +#include "type.h" +#include "server.h" +pthread_mutex_t mutex_clt; -int main(int argc, char *argv[]) -{ - try { - Server BServer(9050,"127.0.0.1",9048); - - while (1) { - request nreq; - nreq.type = "client-square request"; - nreq.data = "request for public key"; - nreq.port = 9050; - packet *pnpkt = new packet(); - SQEServer::Request2Packet(*pnpkt, nreq); - raw_data *pnrwd = new raw_data(); - Server::Packet2Rawdata(*pnpkt, *pnrwd); - BServer.SignedRawdata(pnrwd, "SPKT"); - BServer.SentRawdata(pnrwd); - Server::freeRawdataServer(*pnrwd); - delete pnrwd; - Server::freePcaketServer(*pnpkt); - delete pnpkt; - Addr taddr; - char *buff = nullptr; - if(BServer.socket.RecvRAW(&buff, taddr) > 0){ - printf("Receive: %s\n",buff); - free(buff); +Client::Client(int port, string send_ip,int send_port):socket(port),send_socket(send_ip,send_port){ + socket.UDPSetFCNTL(); + listen_port = port; +} + +void *clientRequestDeamon(void *pvclt){ + clock_thread_info *pclt = (clock_thread_info *) pvclt; + Client *pclient = (Client *) pclt->args; + pclient->ProcessRequestListener(); + clockThreadFinish(pclt->tid); + pthread_exit(NULL); +} + +void *clientRespondDeamon(void *pvclt){ + clock_thread_info *pclt = (clock_thread_info *) pvclt; + Client *pclient = (Client *) pclt->args; + int prm = 512; + ssize_t tlen; + char *str = nullptr; + Addr taddr; + do{ + tlen = pclient->socket.RecvRAW(&str,taddr); + if(tlen > 0){ +// 记录有效数据包 + if(Server::CheckRawMsg(str, tlen)){ + + raw_data *ptrdt = new raw_data(); + Server::ProcessSignedRawMsg(str, tlen, *ptrdt); + ptrdt->address = *(struct sockaddr_in *)taddr.RawObj(); + if (memcmp(&ptrdt->info,"SPKT",sizeof(uint32_t))) { + packet npkt; + Server::Rawdata2Packet(npkt, *ptrdt); + if(npkt.type == RESPOND_TYPE){ + printf("Get Respond.\n"); + respond *pnres = new respond(); + SQEServer::Packet2Respond(npkt, *pnres); +// 加锁 + if (pthread_mutex_lock(&mutex_clt) != 0) throw "lock error"; + pclient->res_lst.push_back(pnres); +// 解锁 + pthread_mutex_unlock(&mutex_clt); + } + Server::freePcaketServer(npkt); + } + else{ + + } + Server::freeRawdataServer(*ptrdt); + delete ptrdt; } - - - } - - } catch (char const *str) { - printf("%s\n",str); - return 0; + free(str); + + }while (tlen && prm-- > 0); + clockThreadFinish(pclt->tid); + pthread_exit(NULL); +} + +void Client::ProcessRequestListener(void){ +// 加锁 + if (pthread_mutex_lock(&mutex_clt) != 0) throw "lock error"; + for(auto &pres : res_lst){ + for(auto &lreq : req_lst){ + if(!lreq->active) continue; +// 检查回复号与请求号是否相同 + if(!memcmp(&lreq->p_req->r_id,&pres->r_id,sizeof(rng::rng64))){ +// 检查是否为源地址发来的回复 + if(!memcmp(lreq->p_req->t_addr.Obj(),pres->t_addr.Obj(),sizeof(sockaddr_in))){ +// 调用回调函数 + lreq->callback(pres); + lreq->active = false; + } + } + } + delete pres; + pres = nullptr; } + res_lst.remove_if([](auto &pres){return pres == nullptr;}); +// 解锁 + pthread_mutex_unlock(&mutex_clt); + +// 处理请求超时的情况 + for (auto lreq : req_lst) { + if(!lreq->active) continue; + if(lreq->clicks < lreq->timeout){ + lreq->clicks++; +// 重新发送数据包 + if(!(lreq->clicks % 2)){ + send_socket.SetSendSockAddr(*lreq->p_req->t_addr.Obj()); + send_socket.SendRAW(lreq->trwd.msg, lreq->trwd.msg_size); + } + } + else{ + delete lreq; + lreq->active = false; + printf("Request TimeOut.\n"); + } + } +// 请求列表 + req_lst.remove_if([](auto &preq){return preq->active == false;}); +} + +void setClientClock(Client *pclient,int clicks){ + pthread_mutex_init(&mutex_clt, nullptr); +// 注册回复数据接收时钟 + clock_register *pncr = new clock_register(); + pncr->if_thread = true; + pncr->if_reset = true; + pncr->click = clicks; + pncr->rawclick = clicks; + pncr->func = clientRespondDeamon; + pncr->arg = (void *)pclient; + newClock(pncr); + +// 注册请求监听处理时钟 + pncr = new clock_register(); + pncr->if_thread = true; + pncr->if_reset = true; + pncr->click = clicks+3; + pncr->rawclick = clicks*2; + pncr->func = clientRequestDeamon; + pncr->arg = (void *)pclient; + newClock(pncr); } + +void Client::NewRequest(request **ppreq,string send_ip,int send_port,string type, string data){ + request *pnreq = new request(); + pnreq->type = type; + pnreq->data = data; + pnreq->t_addr.SetIP(send_ip); + pnreq->t_addr.SetPort(send_port); + pnreq->recv_port = listen_port; + *ppreq = pnreq; +} + +void Client::NewRequestListener(request *preq, int timeout, void (*callback)(respond *)){ + request_listener *pnrl = new request_listener(); + packet npkt; + pnrl->active = true; + pnrl->callback = callback; + pnrl->timeout = timeout; + pnrl->clicks = 0; + pnrl->p_req = preq; + SQEServer::Request2Packet(npkt, *preq); + Server::Packet2Rawdata(npkt, pnrl->trwd); + Server::SignedRawdata(&pnrl->trwd,"SPKT"); + send_socket.SetSendSockAddr(*pnrl->p_req->t_addr.Obj()); + send_socket.SendRAW(pnrl->trwd.msg, pnrl->trwd.msg_size); + req_lst.push_back(pnrl); +} + +request_listener::~request_listener(){ + Server::freeRawdataServer(trwd); + delete p_req; +} diff --git a/src/clock.cpp b/src/clock.cpp index 474a26f..38cb395 100644 --- a/src/clock.cpp +++ b/src/clock.cpp @@ -41,8 +41,6 @@ void newClock(clock_register *pncr){ //时钟滴答调用函数 void threadsClock(int n){ - - // 处理已完成线程 for(auto tid : clock_thread_finished){ clock_thread_info *tcti = clocks_thread_map.find(tid)->second; diff --git a/src/server.cpp b/src/server.cpp index 5fa798e..7a72178 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -278,6 +278,7 @@ void *serverDeamon(void *pvcti){ raw_data *ptrdt = new raw_data(); Server::ProcessSignedRawMsg(str, tlen, *ptrdt); ptrdt->address = *(struct sockaddr_in *)taddr.RawObj(); + printf("[First]: %d\n",taddr.Obj()->); psvr->rawdata_in.push_back(ptrdt); } @@ -467,14 +468,19 @@ void SQEServer::ProcessRequset(void){ } void SQEServer::Packet2Respond(packet &pkt, respond &res){ - + res.r_id = *(uint32_t *)pkt.buffs[0].second; + res.t_addr.SetSockAddr(*(struct sockaddr_in *)pkt.buffs[1].second); + res.type = (const char *)pkt.buffs[2].second; + res.buff_size = pkt.buffs[3].first; + memcpy(res.buff,pkt.buffs[3].second,res.buff_size); } void SQEServer::Respond2Packet(packet &pkt, respond &res){ pkt.type = RESPOND_TYPE; - pkt.address = *res.t_addr.Obj(); + pkt.AddBuff((void *) &res.r_id, sizeof(uint32_t)); + pkt.AddBuff((void *) res.t_addr.Obj(), sizeof(sockaddr_in)); pkt.AddBuff((void *) res.type.data(), (uint32_t)res.type.size()); - pkt.AddBuff((void *)res.buff, res.buff_size); + pkt.AddBuff((void *) res.buff, res.buff_size); } request::request(){ @@ -507,6 +513,7 @@ void Server::ProcessSendPackets(void){ Packet2Rawdata(*ppkt, nrwd); SignedRawdata(&nrwd, "SPKT"); send_socket.SetSendSockAddr(ppkt->address); + printf("[Final]: %d\n",ppkt->address.sin_addr.s_addr); SentRawdata(&nrwd); freeRawdataServer(nrwd); freePcaketServer(*ppkt); diff --git a/src/test.cpp b/src/test.cpp new file mode 100644 index 0000000..83a236c --- /dev/null +++ b/src/test.cpp @@ -0,0 +1,36 @@ +// +// main.cpp +// Netc +// +// Created by 胡一兵 on 2019/1/13. +// Copyright © 2019年 Bakantu. All rights reserved. +// + +#include "instruct.h" + +void getSQEPublicKey(respond *pres); + +int main(int argc, char *argv[]) +{ + try { + Client nclt(9050); + request *preq; + initClock(); + setThreadsClock(); + setClientClock(&nclt,2); + nclt.NewRequest(&preq, "127.0.0.1", 9048, "client-square request", "request for public key"); + nclt.NewRequestListener(preq, 10, getSQEPublicKey); + while (1) { + sleep(10); + } + + } catch (char const *str) { + printf("%s\n",str); + return 0; + } + +} + +void getSQEPublicKey(respond *pres){ + printf("Get Respond.\n"); +}