scketfuncs.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #include "scketfuncs.h"
  2. // Linux环境下的错误代码映射
  3. string FormatLinkError(int ErrorCode) {
  4. switch (ErrorCode) {
  5. case EACCES: return "Permission denied"; // 权限不足
  6. case EADDRINUSE: return "Address already in use"; // 地址已被使用
  7. case ECONNREFUSED: return "Connection refused"; // 连接被拒绝
  8. case ETIMEDOUT: return "Connection timed out"; // 连接超时
  9. case ENETUNREACH: return "Network unreachable"; // 网络不可达
  10. case ECONNRESET: return "Connection reset by peer"; // 连接被对方重置
  11. case ENOTCONN: return "Socket not connected"; // 套接字未连接
  12. case EWOULDBLOCK: return "Operation would block"; // 操作将阻塞
  13. case EINPROGRESS: return "Operation in progress"; // 操作进行中
  14. case EALREADY: return "Operation already in progress"; // 操作已在进行
  15. case EISCONN: return "Socket is already connected"; // 套接字已连接
  16. case ENOBUFS: return "No buffer space available"; // 无缓冲区空间
  17. case EOPNOTSUPP: return "Operation not supported"; // 操作不支持
  18. case EPROTONOSUPPORT: return "Protocol not supported"; // 协议不支持
  19. case ENOTSOCK: return "Not a socket"; // 不是套接字
  20. case EAFNOSUPPORT: return "Address family not supported"; // 地址族不支持
  21. case EINTR: return "Interrupted system call"; // 系统调用中断
  22. case EFAULT: return "Bad address"; // 错误地址
  23. case EMSGSIZE: return "Message too long"; // 消息过长
  24. case EADDRNOTAVAIL: return "Address not available"; // 地址不可用
  25. case EPERM: return "Operation not permitted"; // 操作不允许
  26. case ENOENT: return "No such file or directory"; // 文件或目录不存在
  27. case EIO: return "Input/output error"; // 输入/输出错误
  28. default: return "Socket error " + to_string(ErrorCode); // 默认错误
  29. }
  30. }
  31. // 安全关闭套接字
  32. int CLOSESOCKET(int& s) {
  33. int ret = 0;
  34. if (s != -1) { // Linux中无效套接字为-1
  35. // 设置为阻塞模式以避免未完成操作
  36. int flags = fcntl(s, F_GETFL, 0);
  37. if (flags != -1) {
  38. fcntl(s, F_SETFL, flags & ~O_NONBLOCK);
  39. }
  40. // 先关闭读写通道再关闭套接字
  41. ret = shutdown(s, SHUT_RDWR);
  42. close(s);
  43. s = -1; // 标记为无效套接字
  44. }
  45. return ret;
  46. }
  47. // 设置TCP keep-alive参数
  48. int socket_set_keepalive(int fd) {
  49. int alive = 1;
  50. // 启用keep-alive机制
  51. if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &alive, sizeof(alive))) {
  52. return -1; // 设置失败
  53. }
  54. // 设置空闲时间(秒)
  55. int idle = 10; // 10秒无活动后开始探测
  56. if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle))) {
  57. return -2; // 设置失败
  58. }
  59. // 设置探测间隔(秒)
  60. int interval = 5; // 5秒探测间隔
  61. if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval))) {
  62. return -3; // 设置失败
  63. }
  64. // 设置最大探测次数
  65. int count = 3; // 最多探测3次
  66. if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &count, sizeof(count))) {
  67. return -4; // 设置失败
  68. }
  69. return 0; // 成功
  70. }