From 929d5b9369e9a02f5c9a8bf090bfa960e87d0984 Mon Sep 17 00:00:00 2001 From: Saturneic Date: Fri, 18 Jan 2019 01:25:01 +0800 Subject: [PATCH] structural reformation. --- addr.cpp | 22 ++++- client.cpp | 2 +- main.cpp | 2 +- net.h | 194 ++++++++++++++++++++++++++++++-------- server.cpp | 6 +- server.h | 53 ++++++----- socket.cpp | 269 +++++++++++++++++++---------------------------------- 7 files changed, 298 insertions(+), 250 deletions(-) diff --git a/addr.cpp b/addr.cpp index f5d6432..7a84abc 100644 --- a/addr.cpp +++ b/addr.cpp @@ -34,11 +34,11 @@ Addr::Addr(const Addr &t_addr){ } -socklen_t *Addr::sizep(void){ +socklen_t *Addr::SizeP(void){ return &addr_size; } -socklen_t Addr::size(void){ +socklen_t Addr::Size(void){ return addr_size; } @@ -56,6 +56,20 @@ void Addr::SetIP(string ip_addr){ addr_size = sizeof(address); } -struct sockaddr *Addr::obj(void){ - return (struct sockaddr *) &address; +struct sockaddr_in *Addr::Obj(void){ + return &address; +} + +struct sockaddr *Addr::RawObj(void){ + return (struct sockaddr *)&address; +} + +void Addr::SetIpv4(void){ + address.sin_family = AF_INET; + SetSize(); +} + +void Addr::SetIpv6(void){ + address.sin_family = AF_INET6; + SetSize(); } diff --git a/client.cpp b/client.cpp index 8c9b75a..274fefa 100644 --- a/client.cpp +++ b/client.cpp @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) { try { - Server client("127.0.0.1",9049,"127.0.0.1",9048); + Server client(9049,"127.0.0.1",9048); vector fargs = {1,0,0,1}; vectorargs; CPart::addArg(&args, 12.63); diff --git a/main.cpp b/main.cpp index 3267b0d..f861327 100644 --- a/main.cpp +++ b/main.cpp @@ -17,7 +17,7 @@ int main(void){ initClock(); - Server srvr("127.0.0.1"); + Server srvr(9048); //srvr.Deamon(); vector fargs = {1,0,0,1}; vectorargs; diff --git a/net.h b/net.h index 677de0e..b2e27df 100644 --- a/net.h +++ b/net.h @@ -1,13 +1,13 @@ // -// net.hpp +// net.h // Net // // Created by 胡一兵 on 2019/1/13. // Copyright © 2019年 Bakantu. All rights reserved. // -#ifndef net_hpp -#define net_hpp +#ifndef net_h +#define net_h #include "type.h" @@ -23,9 +23,9 @@ public: Addr(); Addr(const Addr &t_addr); // 获得记录IP地址管理结构的大小的变量本身 - socklen_t *sizep(void); + socklen_t *SizeP(void); // 获得IP地址管理结构大小 - socklen_t size(void); + socklen_t Size(void); // 重新设置IP地址管理结构所对应的端口 void SetPort(int port); // 重新设置IP地址管理结构所对应的IP地址 @@ -33,48 +33,162 @@ public: // IP地址管理结构的大小变量 void SetSize(void); // 获得指向IP地址管理结构的指针 - struct sockaddr *obj(void); + struct sockaddr_in *Obj(void); +// 获得指向IP地址管理结构的指针 + struct sockaddr *RawObj(void); + void SetIpv4(void); + void SetIpv6(void); }; -//套接字管理类 -class Socket{ - struct sockaddr_in c_addr; - Addr addr; - int nsfd,sfd,port; -// 属性记录变量 - bool server,tcp,ipv4,set_fcntl = false; -// 缓冲区 +//服务器套接字类 +class SocketServer{ +protected: +// 套接字操作柄 + int server_sfd; +// 服务器IP及端口管理类 + Addr server_addr; +// 传输协议参数 + int ipptl; +// 临时缓冲区 char buff[BUFSIZ]; +public : + SocketServer(int port,bool ipv4){ + server_addr.SetPort(port); + if(ipv4){ + ipptl = AF_INET; + server_addr.SetIpv4(); + } + else{ + ipptl = AF_INET6; + server_addr.SetIpv6(); + } + } + ~SocketServer(){ + close(server_sfd); + } +// 接受储存简单字符串 + virtual ssize_t Recv(string &str) = 0; +// 接受储存二进制串 + virtual ssize_t RecvRAW(char **p_rdt) = 0; +}; + +//客户端套接字类 +class SocketClient{ +protected: +// 目标服务器IP地址及端口管理类 + Addr send_addr; +// 套接字操作柄 + int client_sfd; +// 传输协议参数 + int ipptl; +// 临时缓冲区 + char buff[BUFSIZ]; +public : + SocketClient(string ip,int port,bool ipv4){ + send_addr.SetIP(ip); + send_addr.SetPort(port); + if(ipv4){ + ipptl = PF_INET; + send_addr.SetIpv4(); + } + else{ + ipptl = PF_INET6; + send_addr.SetIpv6(); + } + } + ~SocketClient(){ + close(client_sfd); + } + // 接受储存简单字符串 + virtual void Send(string buff) = 0; + // 接受储存二进制串 + virtual void SendRAW(char *buff, unsigned long size) = 0; + // 重新设置发送目的地的端口 + void SetSendPort(int port); + // 重新设置发送目的地的IP地址 + void SetSendIP(string ip); +}; + + + + + + + + +//TCP服务器套接字类 +class SocketTCPCServer:public SocketServer{ +// 连接操作柄 + int ctn_sfd; void (*func)(class Socket &,int ,Addr); public: - Socket(string ip_addr, int port, bool server = false, bool tcp = true, bool ipv4 = true); - ~Socket(); -// TCP连接模式下进行端口监听 + SocketTCPCServer(int port):SocketServer(port,true){ +// 获得套接字操作柄 + server_sfd = socket(ipptl,SOCK_STREAM, 0); + if(!~server_sfd) throw "fail to get server sfd"; +// 绑定IP地址与端口 + if(!~bind(server_sfd, server_addr.RawObj(), server_addr.Size())) throw "fail to bind"; + } +// 监听端口 void Listen(int connection, void (*func)(class Socket &,int ,Addr) = NULL); -// TCP链接模式下接受连接 +// 接受连接 void Accept(void); -// TCP模式下发送简单字符串数据 - void Send(int t_nsfd, string buff); -// TCP模式下接收简单字符串数据 - string Recv(int t_nsfd); - -// UDP模式下发送简单字符串数据 - void PacketSend(string buff); -// UDP模式下发送一个带有二进制原始信息的数据包 - void PacketSendRAW(char *buff, unsigned long size); -// UDP模式下接受储存简单字符串信息的数据包 - int PacketRecv(Addr &t_addr, string &str); -// UDP模式下接受储存二进制信息的数据包 - ssize_t PacketRecvRAW(Addr &t_addr, char **p_rdt); -// UDP模式下设置非阻塞模式 - void UDPSetFCNTL(void); - -// 重新设置客户端模式下的发送目的地的端口 - void SetSendPort(int port); -// 重新设置客户端模式下的发送目的地的IP地址 - void SetSendIP(string ip_addr); - +// 接收简单字符串数据 + ssize_t Recv(string &str); +}; + +//TCP客户端套接字类 +class SocketTCPClient:public SocketClient{ +// 连接操作柄 + int ctn_sfd; +public: + SocketTCPClient(string ip,int port):SocketClient(ip,port,true){ +// 获得套接字操作柄 + client_sfd = socket(ipptl,SOCK_STREAM,0); + if(!~client_sfd) throw "fail to get client sfd"; +// 建立TCP连接 + if(!~connect(client_sfd,send_addr.RawObj(),send_addr.Size())) throw "fail to connect"; + } +// 发送简单字符串数据 + void Send(string str); }; -#endif /* net_hpp */ + + + +//UDP服务端套接字类 +class SocketUDPServer:public SocketServer{ +// 是否设置非阻塞 + bool set_fcntl = false; +public: + SocketUDPServer(int port):SocketServer(port,true){ +// 获得套接字操作柄 + server_sfd = socket(ipptl,SOCK_DGRAM,0); + if(!~server_sfd) throw "fail to get server sfd"; +// 绑定IP地址与端口 + if(!~bind(server_sfd, server_addr.RawObj(), server_addr.Size())) throw "fail to bind"; + } +// 接受储存简单字符串信息的数据包 + ssize_t Recv(string &str); +// 接受储存二进制信息的数据包 + ssize_t RecvRAW(char **p_rdt); +// 设置非阻塞模式 + void UDPSetFCNTL(void); +}; + +//UDP客户端套接字类 +class SocketUDPClient:public SocketClient{ +public: + SocketUDPClient(string ip,int port):SocketClient(ip,port,true){ +// 获得套接字操作柄 + client_sfd = socket(ipptl,SOCK_DGRAM,0); + if(!~client_sfd) throw "fail to get client sfd"; + } +// 发送简单字符串数据 + void Send(string buff); +// 发送一个带有二进制原始信息的数据包 + void SendRAW(char *buff, unsigned long size); +}; + +#endif /* net_h */ diff --git a/server.cpp b/server.cpp index 16241e2..c580f93 100644 --- a/server.cpp +++ b/server.cpp @@ -21,7 +21,7 @@ void setServerClock(Server *psvr, int clicks){ clocks_list.push_back(ncr); } -Server::Server(string ip_addr, int port, string send_ip_addr,int send_port):socket(ip_addr,port,true,false),send_socket(send_ip_addr,send_port,false,false){ +Server::Server(int port, string send_ip,int send_port):socket(port),send_socket(send_ip,send_port){ socket.UDPSetFCNTL(); } @@ -186,7 +186,7 @@ void Server::SignedRawdata(struct raw_data *trdt,string info){ } int Server::SentRawdata(struct raw_data *trdt){ - send_socket.PacketSendRAW(trdt->msg, trdt->msg_size); + send_socket.SendRAW(trdt->msg, trdt->msg_size); return 0; } @@ -222,7 +222,7 @@ void *serverDeamon(void *psvr){ char *str = nullptr; printf("Checking Packet.\n"); do{ - tlen = svr.socket.PacketRecvRAW(f_addr,&str); + tlen = svr.socket.RecvRAW(&str); if(tlen > 0){ // 记录有效数据包 if(Server::CheckRawMsg(str, tlen)){ diff --git a/server.h b/server.h index b8924f3..c97e469 100644 --- a/server.h +++ b/server.h @@ -25,26 +25,27 @@ struct compute_result{ vector *fargs_out; }; -struct server_clock{ - Server *psvr; - int click; -}; - -//原始数据包 -struct packet{ +//通用数据包类 +class packet{ +public: unsigned int type; +// 记录块的大小及内容所在的内存地址 vector> buffs; }; -//二进制原始串及其信息标签 -struct raw_data{ +//带标签的二进制串管理结构 +class raw_data{ +public: +// 二进制串 char *data = NULL; unsigned long size = 0; +// 标签 uint32_t head, tail; uint32_t info; +// 信息串 char *msg = NULL; unsigned long msg_size = 0; - +// 用简单字符串直接出适合 void setData(string str){ data = (char *)malloc(str.size()+1); size = str.size()+1; @@ -55,48 +56,36 @@ struct raw_data{ //通用服务器类 class Server{ -public: - vector cpurs_in; +protected: vector packets_in; vector rawdata_in; +public: // 服务器类的接收套接字对象与发送套接字对象 - Socket socket, send_socket; + SocketUDPServer socket; + SocketUDPClient send_socket; int packet_max = 30; - Server(string ip_addr, int port = 9048, string send_ip_addr = "127.0.0.1",int send_port = 9049); + Server(int port = 9048, string send_ip = "127.0.0.1",int send_port = 9049); // 重新设置服务器的发送端口 void SetSendPort(int port); - // 重新设置服务器的发送IP地址 void SetSendIP(string ip_addr); - -// 将计算结果包转化为结构数据包 - static packet CPURS2Packet(compute_result tcpur); - // 将结构数据包转换成二进制串 static raw_data Packet2Rawdata(packet tpkt); // 将通用二进制串转换为通用数据包 static packet Rawdata2Packet(raw_data trdta); - -// 将结构数据包转化为计算结果包 - static compute_result Packet2CPUR(packet *tpkt); - // 释放二进制串占用的空间 static void freeRawdataServer(struct raw_data trdt); // 释放通用数据包包占用 static void freePcaketServer(struct packet tpkt); // 释放计算结果包占用的空间 static void freeCPURServer(struct compute_result tcpur); - // 给二进制串贴上识别标签 static void SignedRawdata(struct raw_data *trdt,string info); - // 发送已经贴上标签的二进制串 int SentRawdata(struct raw_data *trdt); - // 检查消息串是否为一个贴上标签的二进制串 static bool CheckRawMsg(char *p_rdt, ssize_t size); - // 处理一个已贴上标签的原始二进制串,获得其包含的信息 static raw_data ProcessSignedRawMsg(char *p_rdt, ssize_t size); @@ -104,6 +93,16 @@ public: }; +//计算节点服务器类 +class CNodeServer:public Server{ + vector cpurs_in; +public: +// 将计算结果包转化为结构数据包 + static packet CPURS2Packet(compute_result tcpur); +// 将结构数据包转化为计算结果包 + static compute_result Packet2CPUR(packet *tpkt); +}; + //设置服务器守护程序的时钟 void setServerClock(Server *psvr, int clicks); //服务器守护线程 diff --git a/socket.cpp b/socket.cpp index 4e26382..aa51aac 100644 --- a/socket.cpp +++ b/socket.cpp @@ -8,187 +8,108 @@ #include "net.h" +void SocketClient::SetSendPort(int port){ + send_addr.SetPort(port); +} -Socket::Socket(string ip_addr, int port, bool server, bool tcp, bool ipv4){ - struct sockaddr_in &address = *(struct sockaddr_in *)addr.obj(); - if(ipv4) - address.sin_family = AF_INET; - else - address.sin_family = AF_INET6; - address.sin_port = htons(port); - this->port = port; - address.sin_addr.s_addr = inet_addr(ip_addr.data()); - addr.SetSize(); - this->server = server; - this->tcp = tcp; - this->ipv4 = ipv4; - int TAU = SOCK_STREAM; - if(!tcp) TAU = SOCK_DGRAM; - //如果是服务端 - if(server){ - if(ipv4) sfd = socket(AF_INET,TAU,0); - else sfd = socket(AF_INET6,TAU,0); - if(!~sfd) throw "fail to get sfd"; - if(!~bind(sfd, addr.obj(), addr.size())) throw "fail to bind"; +void SocketClient::SetSendIP(string ip){ + send_addr.SetIP(ip); +} + +ssize_t SocketTCPCServer::Recv(string &str){ + ssize_t len=recv(ctn_sfd,buff,BUFSIZ,0); + if(len > 0){ + buff[len] = '\0'; + string str = buff; + return len; + } + else return -1; +} + +void SocketTCPCServer::Listen(int connection, void (*func)(class Socket &,int ,Addr)){ + listen(server_sfd, 10); + this->func = func; +} + +void SocketTCPClient::Send(string str){ + ssize_t len = send(ctn_sfd,str.data(),str.size(),0); + if(len != str.size()) throw "size unmatch"; +} + +ssize_t SocketUDPServer::Recv(string &str){ + ssize_t tlen; +// 非阻塞接收 + if(set_fcntl){ + tlen = recvfrom(server_sfd, buff, BUFSIZ, 0, server_addr.RawObj(), server_addr.SizeP()); +// 读取错误 + if(tlen == -1 && errno != EAGAIN) return -1; +// 缓冲区没有信息 + else if(tlen == 0 || (tlen == -1 && errno == EAGAIN)) return 0; +// 成功读取信息 + else{ + str = buff; + buff[tlen] = '\0'; + return 1; + } + } +// 阻塞接收 + else{ + tlen = recvfrom(server_sfd, buff, BUFSIZ, 0, server_addr.RawObj(), server_addr.SizeP()); + if(~tlen){ + str = buff; + buff[tlen] = '\0'; + return 1; + } + else return -1; + } +} + +ssize_t SocketUDPServer::RecvRAW(char **p_rdt){ + ssize_t tlen; + // 非阻塞输入 + if(set_fcntl){ + tlen = recvfrom(server_sfd, buff, BUFSIZ, 0, server_addr.RawObj(), server_addr.SizeP()); + // 读取错误 + if(tlen == -1 && errno != EAGAIN){ + *p_rdt = nullptr; + return -1; + } + // 缓冲区没有信息 + else if(tlen == 0 || (tlen == -1 && errno == EAGAIN)){ + *p_rdt = nullptr; + return 0; + } + // 成功读取信息 + else{ + *p_rdt = (char *)malloc(tlen); + memcpy(*p_rdt, buff, tlen); + return tlen; + } } else{ - if(ipv4) sfd = socket(PF_INET,TAU,0); - else sfd = socket(PF_INET6,TAU,0); - if(tcp && !~connect(sfd,addr.obj(),addr.size())) - throw "connection fail"; - - } -} - -Socket::~Socket(){ - close(sfd); -} - -void Socket::Listen(int connection, void (*func)(class Socket &,int ,Addr)){ - if(server && tcp){ - listen(sfd, 10); - this->func = func; - } -} - -void Socket::Accept(void){ - if(server && tcp){ - socklen_t scaddr = sizeof(struct sockaddr); - nsfd = accept(sfd,(struct sockaddr *) &c_addr, &scaddr); - Addr addr(c_addr); - if(~nsfd){ - if(func != NULL) func(*this,nsfd,addr); - close(nsfd); - } - } -} - -void Socket::Send(int t_nsfd, string buff){ - if(tcp){ - ssize_t len = send(t_nsfd,buff.data(),buff.size(),0); - if(len != buff.size()) throw "size unmatch"; - } -} - -void Socket::PacketSend(string buff){ - if(!tcp) - sendto(sfd, buff.data(), buff.size(), 0, addr.obj(), addr.size()); -} - -void Socket::SetSendPort(int port){ - if(!server){ - addr.SetPort(port); - } -} - -void Socket::SetSendIP(string ip_addr){ - if(!server){ - addr.SetIP(ip_addr); - } -} -void Socket::PacketSendRAW(char *buff, unsigned long size){ - if(!tcp) - sendto(sfd, buff, size, 0, addr.obj(), addr.size()); -} - -int Socket::PacketRecv(Addr &t_addr, string &str){ - if(!tcp){ - ssize_t tlen; - // 非阻塞输入 - if(set_fcntl){ - tlen = recvfrom(sfd, (void *)buff, BUFSIZ, 0, t_addr.obj(), t_addr.sizep()); - // 读取错误 - if(tlen == -1 && errno != EAGAIN){ - str = ""; - return -1; - } - // 缓冲区没有信息 - else if(tlen == 0 || (tlen == -1 && errno == EAGAIN)){ - str = ""; - return 0; - } - // 成功读取信息 - else{ - str = buff; - buff[tlen] = '\0'; - return 1; - } + tlen = recvfrom(server_sfd, buff, BUFSIZ, 0, server_addr.RawObj(), server_addr.SizeP()); + if(~tlen){ + *p_rdt = (char *)malloc(tlen); + memcpy(p_rdt, buff, tlen); + return tlen; } else{ - tlen = recvfrom(sfd, (void *)buff, BUFSIZ, 0, t_addr.obj(), t_addr.sizep()); - if(~tlen){ - str = buff; - buff[tlen] = '\0'; - return 1; - } - else{ - str = ""; - return -1; - } - + *p_rdt = nullptr; + return -1; } } - throw "connection is tcp"; -} - -ssize_t Socket::PacketRecvRAW(Addr &t_addr, char **p_rdt){ - if(!tcp){ - ssize_t tlen; - // 非阻塞输入 - if(set_fcntl){ - tlen = recvfrom(sfd, (void *)buff, BUFSIZ, 0, t_addr.obj(), t_addr.sizep()); - // 读取错误 - if(tlen == -1 && errno != EAGAIN){ - *p_rdt = nullptr; - return -1; - } - // 缓冲区没有信息 - else if(tlen == 0 || (tlen == -1 && errno == EAGAIN)){ - *p_rdt = nullptr; - return 0; - } - // 成功读取信息 - else{ - *p_rdt = (char *)malloc(tlen); - memcpy(*p_rdt, buff, tlen); - return tlen; - } - } - else{ - tlen = recvfrom(sfd, (void *)buff, BUFSIZ, 0, t_addr.obj(), t_addr.sizep()); - if(~tlen){ - *p_rdt = (char *)malloc(tlen); - memcpy(p_rdt, buff, tlen); - return tlen; - } - else{ - *p_rdt = nullptr; - return -1; - } - - } - } - throw "connection is tcp"; -} - -void Socket::UDPSetFCNTL(void){ - if(!tcp){ - int flags = fcntl(sfd, F_GETFL, 0); - fcntl(sfd, F_SETFL, flags | O_NONBLOCK); - set_fcntl = true; - } } -string Socket::Recv(int t_nsfd){ - if(tcp){ - char buff[BUFSIZ]; - ssize_t len=recv(t_nsfd,buff,BUFSIZ,0); - if(len > 0){ - buff[len] = '\0'; - string str = buff; - return str; - } - else throw "receive fail"; - } - throw "connection is udp"; +void SocketUDPServer::UDPSetFCNTL(void){ + int flags = fcntl(server_sfd, F_GETFL, 0); + fcntl(server_sfd, F_SETFL, flags | O_NONBLOCK); + set_fcntl = true; +} + +void SocketUDPClient::Send(string buff){ + sendto(client_sfd, buff.data(), buff.size(), 0, send_addr.RawObj(), send_addr.Size()); +} + +void SocketUDPClient::SendRAW(char *buff, unsigned long size){ + sendto(client_sfd, buff, size, 0, send_addr.RawObj(), send_addr.Size()); }