Older/ToolKit/Network/sockutil.h

355 lines
10 KiB
C
Raw Permalink Normal View History

2024-09-28 23:55:00 +08:00
/*
* Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
*
* This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef NETWORK_SOCKUTIL_H
#define NETWORK_SOCKUTIL_H
#if defined(_WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#pragma comment (lib, "Ws2_32.lib")
#pragma comment(lib,"Iphlpapi.lib")
#else
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif // defined(_WIN32)
#include <cstring>
#include <cstdint>
#include <map>
#include <vector>
#include <string>
namespace toolkit {
#if defined(_WIN32)
#ifndef socklen_t
#define socklen_t int
#endif //!socklen_t
int ioctl(int fd, long cmd, u_long *ptr);
int close(int fd);
#endif // defined(_WIN32)
#if !defined(SOCKET_DEFAULT_BUF_SIZE)
#define SOCKET_DEFAULT_BUF_SIZE (256 * 1024)
#else
#if SOCKET_DEFAULT_BUF_SIZE == 0 && !defined(__linux__)
// just for linux, because in some high-throughput environments,
// kernel control is more efficient and reasonable than program
// settings. For example, refer to cloudflare's blog
#undef SOCKET_DEFAULT_BUF_SIZE
#define SOCKET_DEFAULT_BUF_SIZE (256 * 1024)
#endif
#endif
#define TCP_KEEPALIVE_INTERVAL 30
#define TCP_KEEPALIVE_PROBE_TIMES 9
#define TCP_KEEPALIVE_TIME 120
//套接字工具类封装了socket、网络的一些基本操作
class SockUtil {
public:
/**
* tcp客户端套接字并连接服务器
* @param host ip或域名
* @param port
* @param async
* @param local_ip ip
* @param local_port
* @return -1socket fd号
*/
static int connect(const char *host, uint16_t port, bool async = true, const char *local_ip = "::", uint16_t local_port = 0);
/**
* tcp监听套接字
* @param port
* @param local_ip ip
* @param back_log accept列队长度
* @return -1socket fd号
*/
static int listen(const uint16_t port, const char *local_ip = "::", int back_log = 1024);
/**
* udp套接字
* @param port
* @param local_ip ip
* @param enable_reuse bind端口
* @return -1socket fd号
*/
static int bindUdpSock(const uint16_t port, const char *local_ip = "::", bool enable_reuse = true);
/**
* @brief sock
* @param sock, socket fd
* @return 0 , -1
*/
static int dissolveUdpSock(int sock);
/**
* TCP_NODELAYTCP交互延时
* @param fd socket fd号
* @param on
* @return 0-1
*/
static int setNoDelay(int fd, bool on = true);
/**
* socket不触发SIG_PIPE信号(mac有效)
* @param fd socket fd号
* @return 0-1
*/
static int setNoSigpipe(int fd);
/**
* socket是否阻塞
* @param fd socket fd号
* @param noblock
* @return 0-1
*/
static int setNoBlocked(int fd, bool noblock = true);
/**
* socket接收缓存8K左右
*
* @param fd socket fd号
* @param size
* @return 0-1
*/
static int setRecvBuf(int fd, int size = SOCKET_DEFAULT_BUF_SIZE);
/**
* socket接收缓存8K左右
*
* @param fd socket fd号
* @param size
* @return 0-1
*/
static int setSendBuf(int fd, int size = SOCKET_DEFAULT_BUF_SIZE);
/**
* (TIME_WAITE状态)
* @param fd socket fd号
* @param on
* @return 0-1
*/
static int setReuseable(int fd, bool on = true, bool reuse_port = true);
/**
* udp广播信息
* @param fd socket fd号
* @param on
* @return 0-1
*/
static int setBroadcast(int fd, bool on = true);
/**
* TCP KeepAlive特性
* @param fd socket fd号
* @param on
* @param idle keepalive空闲时间
* @param interval keepalive探测时间间隔
* @param times keepalive探测次数
* @return 0-1
*/
static int setKeepAlive(int fd, bool on = true, int interval = TCP_KEEPALIVE_INTERVAL, int idle = TCP_KEEPALIVE_TIME, int times = TCP_KEEPALIVE_PROBE_TIMES);
/**
* FD_CLOEXEC特性()
* @param fd fd号socket
* @param on
* @return 0-1
*/
static int setCloExec(int fd, bool on = true);
/**
* SO_LINGER特性
* @param sock socket fd号
* @param second socket超时时间
* @return 0-1
*/
static int setCloseWait(int sock, int second = 0);
/**
* dns解析
* @param host ip
* @param port
* @param addr sockaddr结构体
* @return
*/
static bool getDomainIP(const char *host, uint16_t port, struct sockaddr_storage &addr, int ai_family = AF_INET,
int ai_socktype = SOCK_STREAM, int ai_protocol = IPPROTO_TCP, int expire_sec = 60);
/**
* ttl
* @param sock socket fd号
* @param ttl ttl值
* @return 0-1
*/
static int setMultiTTL(int sock, uint8_t ttl = 64);
/**
*
* @param sock socket fd号
* @param local_ip ip
* @return 0-1
*/
static int setMultiIF(int sock, const char *local_ip);
/**
*
* @param fd socket fd号
* @param acc
* @return 0-1
*/
static int setMultiLOOP(int fd, bool acc = false);
/**
*
* @param fd socket fd号
* @param addr
* @param local_ip ip
* @return 0-1
*/
static int joinMultiAddr(int fd, const char *addr, const char *local_ip = "0.0.0.0");
/**
* 退
* @param fd socket fd号
* @param addr
* @param local_ip ip
* @return 0-1
*/
static int leaveMultiAddr(int fd, const char *addr, const char *local_ip = "0.0.0.0");
/**
*
* @param sock socket fd号
* @param addr
* @param src_ip
* @param local_ip ip
* @return 0-1
*/
static int joinMultiAddrFilter(int sock, const char *addr, const char *src_ip, const char *local_ip = "0.0.0.0");
/**
* 退
* @param fd socket fd号
* @param addr
* @param src_ip
* @param local_ip ip
* @return 0-1
*/
static int leaveMultiAddrFilter(int fd, const char *addr, const char *src_ip, const char *local_ip = "0.0.0.0");
/**
* socket当前发生的错误
* @param fd socket fd号
* @return
*/
static int getSockError(int fd);
/**
*
* @return vector<map<ip:name> >
*/
static std::vector<std::map<std::string, std::string>> getInterfaceList();
/**
* ip
*/
static std::string get_local_ip();
/**
* socket绑定的本地ip
* @param sock socket fd号
*/
static std::string get_local_ip(int sock);
/**
* socket绑定的本地端口
* @param sock socket fd号
*/
static uint16_t get_local_port(int sock);
/**
* socket绑定的远端ip
* @param sock socket fd号
*/
static std::string get_peer_ip(int sock);
/**
* socket绑定的远端端口
* @param sock socket fd号
*/
static uint16_t get_peer_port(int sock);
static bool support_ipv6();
/**
* 线in_addr转ip字符串
*/
static std::string inet_ntoa(const struct in_addr &addr);
static std::string inet_ntoa(const struct in6_addr &addr);
static std::string inet_ntoa(const struct sockaddr *addr);
static uint16_t inet_port(const struct sockaddr *addr);
static struct sockaddr_storage make_sockaddr(const char *ip, uint16_t port);
static socklen_t get_sock_len(const struct sockaddr *addr);
static bool get_sock_local_addr(int fd, struct sockaddr_storage &addr);
static bool get_sock_peer_addr(int fd, struct sockaddr_storage &addr);
/**
* ip
* @param if_name
*/
static std::string get_ifr_ip(const char *if_name);
/**
*
* @param local_op ip
*/
static std::string get_ifr_name(const char *local_op);
/**
*
* @param if_name
*/
static std::string get_ifr_mask(const char *if_name);
/**
* 广
* @param if_name
*/
static std::string get_ifr_brdaddr(const char *if_name);
/**
* ip是否为同一网段
* @param src_ip ip
* @param dts_ip ip
*/
static bool in_same_lan(const char *src_ip, const char *dts_ip);
/**
* ipv4地址
*/
static bool is_ipv4(const char *str);
/**
* ipv6地址
*/
static bool is_ipv6(const char *str);
};
} // namespace toolkit
#endif // !NETWORK_SOCKUTIL_H