• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2023-09-09 14:28 Aet 隐藏边栏 |   抢沙发  10 
文章评分 1 次,平均分 5.0

WIN32_LEAN_AND_MEAN

  1. 一个预处理宏,用于控制 Windows 头文件中包含哪些内容
    1. 具体来说,定义这个宏会减少 Windows 头文件中包含的一些不常用的头文件和 API,从而减小编译时间并减少编译产生的二进制文件的大小
    2. 比如在包含 windows.h 之前定义了 WIN32_LEAN_AND_MEAN,一些较少使用的头文件和 API(如 WinSocketsCryptographic APIWindows 帮助等)就不会被包含进来

MAKEWORD

  1. 用于将两个字节(一个字节为 8 位)组合成一个 WORD(一个 WORD16 位)
  2. 主要用于初始化 Winsock 库的版本

关于版本

  1. 可能包括:
    1. Winsock 1.1
    2. Winsock 2.0
    3. Winsock 2.1
    4. Winsock 2.2
  2. 实际应用中,一般会使用 2.2 版本,因为它提供了最全面的功能支持,并且向下兼容到更早的版本
  3. 某些操作系统版本中可能只支持特定的 Winsock 版本
    1. Windows 95Windows 98 通常只支持到 Winsock 1.1
    2. Windows XP 和更高版本通常会支持 Winsock 2.0 甚至更高
  4. 返回值
    1. 使用 WSAStartup 函数初始化 Winsock 库时,如果请求的版本不受支持,该函数会返回错误

recv返回值

解析

  1. 接收到数据,返回值是正值
  2. 客户端正常关闭连接,返回值是0
  3. 客户端被强制结束了或网络故障,返回值是-1

errno

  1. errno 是一个全局变量,用于许多 C C++ 的标准库函数来指示特定的错误情况
    1. 这些函数遇到错误时,它们通常会返回一个错误代码(例如 -1NULL),并设置 errno 以提供有关错误的更多信息
  2. 主要用途是提供关于系统调用和某些库函数失败原因的更详细信息
  3. 详细值:
    1. EACCES: 权限被拒绝
    2. EAGAINEWOULDBLOCK: 资源暂时不可用
    3. EBADF: 错误的文件描述符
    4. ECONNRESET: 对端重置了连接
    5. EINTR: 被信号中断
    6. EINVAL: 无效的参数
    7. ENOMEM: 没有足够的内存
    8. ENOTSOCK: 描述符不是一个socket
  4. 正确的使用方法:

  1. Windows上,errno 不是主要用于标识WinSock错误的机制
    1. 当使用WinSock API(如 recv)时,你应该使用 WSAGetLastError 函数来获取错误代码

WSAGetLastError

  1. 函数返回上一个WinSock函数调用的错误代码
    1. 这与标准C库中的 errno 变量有点相似,但它是专门为WinSock设计的
  2. 常见错误代码:
    1. WSAEACCES: 试图访问一个受权限保护的socket
    2. WSAECONNRESET: 对端执行了一个reset
    3. WSAEWOULDBLOCK: 非阻塞操作没有立即完成
    4. WSAENOTSOCK: 描述符不是一个socket
    5. WSAETIMEDOUT: 连接尝试没有成功,或连接已断开,因为连接相关的活动没有在给定的时间段内完成
  3. 示例:

  1. 想为错误代码获取描述性的错误消息,你可以使用 FormatMessage 函数

FormatMessage

  1. Windows编程中遇到一个错误代码,如 GetLastErrorWSAGetLastError 返回的代码,可以使用 FormatMessage 来得到该错误代码对应的描述性错误消息
    1. 这个函数可以从系统的错误代码表中检索本地化的错误消息描述,或者从用户定义的消息表资源中检索消息
  2. 示例:

  1. 控制台编码不对时,会导致显示中文乱码

std::locale

  1. 当你设置全局locale使用 std::locale::global(std::locale("")); 后,它会在程序的整个运行期间有效,除非你再次更改它
  2. 这个设置将会影响所有使用标准C++库和全局locale设置的函数和对象
    1. 例如,这将影响到输入/输出流(如 std::coutstd::cin)、字符串格式化和解析函数,以及其他任何依赖locale的操作
  3. 在多线程环境中,std::locale::global 的行为可能不是线程安全的
    1. 这意味着如果你在一个线程中更改了它,其他线程可能会受到未预期的影响

线程局部local

  1. 当一个变量被声明为thread_local时,每个线程都会为该变量创建一个单独的存储区域,这与全局变量或静态变量不同
    1. 当一个线程修改其版本的myLocale时,它不会影响到其他线程中的myLocale实例
  2. thread_local可以用于任何数据类型,包括基本类型、对象、指针、数组等
    1. 关键是这些变量的每个线程都有其独立的实例
  3. 当线程开始时,thread_local变量会按照它们的声明顺序进行初始化
    当线程结束时,它们会按照与声明相反的顺序进行销毁
  4. 不是所有的编译器和平台都完全支持thread_local
    1. 所以在使用之前,请确保你的开发环境支持这一特性

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享