- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
总有一天。我为 C++ (Visual Studio 2015) 编写了类似于 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();
因此,我不知道套接字状态,套接字死了,或者套接字仍在等待接收数据。
因此,我使用了一种存储 WSAGetLastError()
的方法在 std::string
之前返回值的方法,然后使用 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++11 编译器,您可以:
ssize_t recvsz = ::recv(socket, &str[0], str.size(), 0);
那是因为 &str[0]
是指向实际字符串缓冲区的指针(在非 const
上下文中),并且因为从 C++11 开始数据是保证被存储连续地。从技术上讲,在此之前并没有那么多(尽管在实践中基本上总是如此)。
否则,您将不得不自己分配一个小的 char[]
缓冲区来接收数据。您几乎可以免费为它提供自动存储持续时间,除非您使用的嵌入式系统具有严格的资源限制(但无论如何您都不会使用 string
)。
顺便说一句,请注意您的返回类型:size_t
是无符号的。 recv
返回一个 ssize_t
,它已签名并且可能为负数以指示错误情况。
const size_t BUF_SIZE = 256;
char buf[BUF_SIZE];
ssize_t recvsz = ::recv(socket, &buf[0], BUF_SIZE, 0);
if (recvsz < 0) {
// ... handling
}
// Now, optionally:
std::string str(buf, recvsz);
现在,所有这些都已修复,答案是 the "last error" is permitted to be changed even by a successful operation .所以,是的,如果你想保留它,你必须保存然后重新设置以前的“最后一个错误”值。这似乎确实具有可疑的值(value)——为什么不在产生错误的地方处理它?在发生错误后继续进行似乎是一种糟糕的经商方式。
关于c++ - 为什么 std::string 使 WSAGetLastError 返回零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48749733/
我正在调用 ConnectEx() 方法。它返回 FALSE 值,因此我使用 WSAGetLastError 调用检查错误代码。有时会出现返回值为零的情况。这是什么意思? 最佳答案 发生错误时应立即调
如何从 WinAPI 调用 WSAGetLastError() 以便获得有效的文本错误? 最佳答案 [DllImport("ws2_32.dll", CharSet = CharSet.Auto, S
好吧..我不太确定那是什么意思,但我的系统运行并运行再运行而不会因内存不足而哭泣... 我猜这与系统错误 122 有关,因为在 winsock 错误代码(MSDN)中没有 122... 有人知道吗?.
我正在将一些套接字代码从 Linux 移植到 Windows。 在 Linux 中,我可以使用 strerror() 将 errno 代码转换为人类可读的字符串。 MSDN 文档显示了从 WSAGet
我的代码中有这样的东西 WSADATA wsadata; int error = WSAStartup(0x0202, &wsadata); SOCKADDR_IN targe
你好,我是一名初学者 socket/c 程序员,在本教程中我发现连接函数返回 10038 错误。请帮忙。我做错了什么? 还有什么 winsock 和 winsock2 之间的区别?同样在 connec
在我的代码中,我有带 I/O 完成端口的异步 I/O,对于读/写完成回调,我得到一个 HANDLE(当然可以是套接字、文件句柄、命名管道等)。 所以如果在这样的例程中出现问题,我想检查错误,但是如何知
我创建了一个连接到 C++ 服务器的 C++ 客户端。它连接并正确地将数据发送到服务器。我创建了一个单独的线程来从服务器接收数据,这是我无法弄清楚的问题。我收到此错误: WSAGetLastError
我正在从 Visual Studio 2013 更新到 Visual Studio 2015 并注意到这种行为差异。 #include #include #include int main()
我正在编写一个简单的套接字程序,我想在某些情况下抛出一个错误,以便更容易地捕获错误。为了得到错误,我使用了 WSAGetLastError()。这仅返回与错误关联的代码,我无法抛出该代码,因为抛出错误
我的代码在 Windows 上表现得很奇怪,但在 Linux 上工作...这是我的 server.cpp: #include #include "packet.h" #include "socket
这可能是一个重复的问题,但我已经阅读了其他线程和解决方案,并没有发现代码中遗漏任何内容。那里有些我无法弄清楚的东西。 下面是UDP服务器的代码 #pragma once #pragma comment
我调用了 WSARecv(),它返回了 WSA_IO_PENDING。然后我从另一端发送了一个 RST 数据包。存在于另一个线程中的 GetQueuedCompletionStatus() 函数按预期
总有一天。我为 C++ (Visual Studio 2015) 编写了类似于 Python 内置套接字库的套接字包装器类 所有功能都运行良好。但是,我发现我写的一些函数有问题。 使用后std::st
标题也许说明了一切? Windows 10、Visual Studio Community 2017。 C++ 服务器监听一个端口,并将生成的 FD 放入一个 fd_set 中用于输入,一个用于异常。
这个片段是一个函数的一部分,当套接字连接(或连接)时应该返回 true,如果有任何失败则返回 false。 if(bind(socket_, reinterpret_cast(&any), s
我有一段代码在 Windows 上调用 recv()。 recv() 有时会返回 -1。调用 WSAGetLastError() 返回 0。这似乎是非常奇怪的行为。以前有没有人注意到这一点。 最佳答案
我目前正在将一些 Windows 移动 C++ 代码移植到标准 C++。 所以我正在尝试为 Windows 特定功能寻找替代方案。 我很幸运地找到了一个可以帮助我替换 WSAGetLastError(
我是一名优秀的程序员,十分优秀!