【发布时间】:2018-07-22 19:34:06
【问题描述】:
总有一天。我为 C++ (Visual Studio 2015) 编写了 Socket 包装类,例如 Python 内置套接字库
所有功能都运行良好。但是,我发现我写的一些函数有问题。
使用std::string 的方法如.size()、.clear()、WSAGetLastError() 后总是返回零。
std::string str = "Hello, world";
size_t recvsz = ::send(socket, str.c_str(), str.size(), 0);
// Why always return zero after using std::string's methods?
int err = ::WSAGetLastError();
因此,我无法知道socket的状态,socket死了,或者socket还在等待接收数据。
所以,我使用了在std::string 的方法之前存储WSAGetLastError() 返回值的方法,然后使用WSASetLastError() 恢复它。
std::string str = "Hello, world";
// Before using std::string's methods
int err = ::WSAGetLastError();
size_t recvsz = ::send(socket, str.c_str(), str.size(), 0);
// Restore error value after std::string's methods
::WSASetLastError(err);
我使用的方法是否正确?或者为什么std::string 会导致最后一个错误归零?
已编辑:哇...我错了.. :(。我使用 ::send 而不是 ::recv。抱歉让您感到困惑
SOCKET socket;
char buf[100] = {0x00,};
std::string data, temp_buf;
ssize_t recvsz = ::recv(socket, buf, 99, 0);
// When err has proper error code before std::string methods
// It just for a test
// int err = ::WSAGetLastError();
temp_buf = buf;
data += buf;
int err = WSAGetLastError(); // Always return zero!
【问题讨论】:
-
如果您实际使用的是 C++17 而不是 C++11,则可以调用
str.data()来获取非常量缓冲区。 -
当函数没有失败时,WSAGetLastError() 的返回值是完全不可预知的。修复你的代码,只有在 recv() 返回 SOCKET_ERROR 时才调用它。
-
你怎么知道零不是
recv设置的?你是在强迫它失败吗? -
你在做什么之前
recv与WSAGetLastError绝对无关之后recv以防万一失败 -
我使用的方法正确吗? - 不,错。你必须使用设置
send的WSAGetLastError,以防万一失败,但不要恢复到之前的状态
标签: c++ sockets c++11 winapi winsock