#pragma once #include #include #include #include #include #include #include "base.h" namespace sccl { namespace hardware { namespace net { namespace net_socket { #define MAX_IFS 16 // 最大接口数量 #define MAX_IF_NAME_SIZE 16 // 每个接口名称的最大长度 #define SLEEP_INT 1000 // 连接重试的休眠间隔,单位为微秒 #define RETRY_REFUSED_TIMES 2e4 // 在报告超时之前,连接被拒绝的重试次数(总计20秒) #define RETRY_TIMEDOUT_TIMES 3 // 连接超时的重试次数(每次重试可能需要20秒) #define SOCKET_NAME_MAXLEN (NI_MAXHOST + NI_MAXSERV) // 套接字名称的最大长度,包括主机名和服务名 #define SCCL_SOCKET_MAGIC 0x564ab9f2fc4b9d6cULL // 用于标识套接字的魔数 /* 用于存储IPv4/IPv6通用套接字地址的联合体 */ union scclSocketAddress { // 联合体用于存储不同类型的套接字地址 struct sockaddr sa; // 通用套接字地址 struct sockaddr_in sin; // IPv4套接字地址 struct sockaddr_in6 sin6; // IPv6套接字地址 }; enum scclSocketState : uint8_t { scclSocketStateNone = 0, // 未定义状态 scclSocketStateInitialized = 1, // 已初始化状态 scclSocketStateAccepting = 2, // 正在接受连接状态 scclSocketStateAccepted = 3, // 已接受连接状态 scclSocketStateConnecting = 4, // 正在连接状态 scclSocketStateConnectPolling = 5, // 连接轮询状态 scclSocketStateConnected = 6, // 已连接状态 scclSocketStateReady = 7, // 准备就绪状态 scclSocketStateClosed = 8, // 已关闭状态 scclSocketStateError = 9, // 错误状态 scclSocketStateNum = 10 // 状态总数 }; enum scclSocketType : uint8_t { scclSocketTypeUnknown = 0, // 未知类型 scclSocketTypeBootstrap = 1, // 启动类型 scclSocketTypeProxy = 2, // 代理类型 scclSocketTypeNetSocket = 3, // 网络套接字类型 scclSocketTypeNetIb = 4 // 网络Infiniband类型 }; struct scclSocket { int fd; // 文件描述符 int acceptFd; // 接受连接的文件描述符 int timedOutRetries; // 超时重试次数 int refusedRetries; // 被拒绝重试次数 union scclSocketAddress addr; // 套接字地址 volatile uint32_t* abortFlag; // 中止标志 int asyncFlag; // 异步标志 enum scclSocketState state; // 套接字状态 int salen; // 地址长度 uint64_t magic; // 魔术数 enum scclSocketType type; // 套接字类型 }; #define SCCL_SOCKET_SEND 0 #define SCCL_SOCKET_RECV 1 //////////////////////////////////// socket工具 //////////////////////////////////// // 将地址转换为字符串 const char* scclSocketToString(const union scclSocketAddress* addr, char* buf, const int numericHostForm = 1); // 从字符串中获取地址 scclResult_t scclSocketGetAddrFromString(union scclSocketAddress* ua, const char* ip_port_pair); // 查找与子网匹配的接口 int scclFindInterfaceMatchSubnet(char* ifNames, union scclSocketAddress* localAddrs, union scclSocketAddress* remoteAddr, int ifNameMaxSize, int maxIfs); // 查找可用的socket网络接口 int scclFindSocketInterfaces(char* ifNames, union scclSocketAddress* ifAddrs, int ifNameMaxSize, int maxIfs); //////////////////////////////////// socket基础操作 //////////////////////////////////// // 进行socket操作 scclResult_t scclSocketProgress(int op, struct scclSocket* sock, void* ptr, int size, int* offset); // 等待socket操作完成 scclResult_t scclSocketWait(int op, struct scclSocket* sock, void* ptr, int size, int* offset); // 发送数据 scclResult_t scclSocketSend(struct scclSocket* sock, void* ptr, int size); // 接收数据 scclResult_t scclSocketRecv(struct scclSocket* sock, void* ptr, int size); // 尝试接收数据 scclResult_t scclSocketTryRecv(struct scclSocket* sock, void* ptr, int size, int* closed, bool blocking); // 关闭socket scclResult_t scclSocketClose(struct scclSocket* sock); //////////////////////////////////// 应用socket //////////////////////////////////// // 初始化一个socket scclResult_t scclSocketInit(struct scclSocket* sock, union scclSocketAddress* addr = NULL, uint64_t magic = SCCL_SOCKET_MAGIC, enum scclSocketType type = scclSocketTypeUnknown, volatile uint32_t* abortFlag = NULL, int asyncFlag = 0); // 创建一个监听socket。sock->addr可以预先填充IP和端口信息。成功调用后设置sock->fd scclResult_t scclSocketListen(struct scclSocket* sock); // 获取socket地址 scclResult_t scclSocketGetAddr(struct scclSocket* sock, union scclSocketAddress* addr); // 连接到sock->addr。成功调用后设置sock->fd。 scclResult_t scclSocketConnect(struct scclSocket* sock, int portReuse = 0); // 返回socket连接状态。 scclResult_t scclSocketReady(struct scclSocket* sock, int* running); // 接受来自listenSock->fd的传入连接,并在sock->fd中保持文件描述符,远程端IP/端口在sock->addr中。 scclResult_t scclSocketAccept(struct scclSocket* sock, struct scclSocket* ulistenSock); // 获取socket文件描述符 scclResult_t scclSocketGetFd(struct scclSocket* sock, int* fd); // 设置socket文件描述符 scclResult_t scclSocketSetFd(int fd, struct scclSocket* sock); } // namespace net_socket } // namespace net } // namespace hardware } // namespace sccl