C++ 这些通过套接字发送/接收字符串的函数有什么问题?
我正在尝试编写两种通过套接字发送和接收字符串的方法。这是为了清理Windows的遗留代码,它使用了散布在各处的C++ 这些通过套接字发送/接收字符串的函数有什么问题?,c++,sockets,C++,Sockets,我正在尝试编写两种通过套接字发送和接收字符串的方法。这是为了清理Windows的遗留代码,它使用了散布在各处的send和recv,因此我想让它发挥作用来清理一下。你可以在下面看到我的想法。不幸的是,当我在代码中像这样使用函数时: std::string buffer = receiveStringFromSocket(); 及 我的代码被锁定,甚至不再达到断点 谁能告诉我我做错了什么?我很难调试它,因为我对C/C++不是很熟悉。这可能是错误在混乱的代码库中的其他地方 发送StringToSoc
send
和recv
,因此我想让它发挥作用来清理一下。你可以在下面看到我的想法。不幸的是,当我在代码中像这样使用函数时:
std::string buffer = receiveStringFromSocket();
及
我的代码被锁定,甚至不再达到断点
谁能告诉我我做错了什么?我很难调试它,因为我对C/C++不是很熟悉。这可能是错误在混乱的代码库中的其他地方
发送StringToSocket:
int sendStringToSocket(std::string sendString)
{
char sendBuffer[1024];
memset(sendBuffer, 0, sizeof(sendBuffer)); //Clear the buffer
//sendString.copy(sendBuffer, sendString.length());
strcpy(sendBuffer, sendString.c_str());
cout << "string buffer content:" << endl << cout.write(sendBuffer,sendString.length()) << endl;
rc = send(acceptsocket, sendBuffer, sizeof(sendBuffer)-1, 0);
return rc;
}
std::string receiveStringFromSocket()
{
char receptionBuffer[1024];
memset(receptionBuffer, 0, sizeof(receptionBuffer)); //Clear the buffer
rc = recv(acceptsocket, receptionBuffer, sizeof(receptionBuffer)-1, 0);
string str(receptionBuffer);
return str;
}
对于发送:主要问题是您不需要sendbuffer:您可以将
sendString.c_str()
传递给send()
函数。注释中描述了使用sendbuffer带来的问题
接收:必须检查recv()
的返回值。不知道网络上会出什么问题
组合:在TCP(假设您正在使用)中,无法保证每次发送调用的字节数与每次recv调用的字节数相同。您必须执行一些检查,以查看是否收到了所有需要的字节(最简单的是:发送和检查空字节)。对于小于50字节的字符串,可能不会注意到这一点,但在某些情况下,您将丢失字符串的一部分。主要问题是,send和recv都不能保证发送/接收的数据与您预期的大小相同。所以你需要一些函数,这些函数依赖于这个事实。例如:
void sendBuffer( const char *buff, size_t size )
{
for( size_t sent = 0; sent != size; ) {
int rc = send( socket, buff + sent, size - sent );
if( rc <= 0 ) { // handle error here
}
sent += static_cast<size_t>( rc );
}
}
void sendBuffer(常量字符*buff,大小)
{
对于(发送的大小=0;发送的!=size;){
int rc=send(套接字,buff+sent,size-sent);
如果(很好,您提到的断点表明您知道如何使用调试器。与其等到遇到断点,不如一次一行地遍历整个代码,直到确定它被卡住的位置。问题中没有任何说明表明所示的两个函数中的任何一个有问题。您是输入的数据超过了应输入的数据量,并且将更多的数据复制到接收的字符串中。对于发送:如果字符串大于缓冲区怎么办?为什么即使字符串只是一个字符也要发送整个缓冲区?您可以使用sendString.c_str()调用send
直接发送sendString.size()+1
字节(终止符为+1),因此根本不需要临时缓冲区,也不需要复制。不要使用strcpy,这可能会导致缓冲区溢出。这两个客户端都需要与服务器通信。如果这很重要的话。另外:我知道我应该检查溢出,但因为我知道在两侧发送的字符串/字符数组的长度,所以我是bliS完全忽略了这一点。考虑到这些因素,只关注两个函数:它们是否有效?@JoachimPileborg感谢您的建议-我会尝试。好的。感谢您的建议。我会尝试。我基本上是在使用代码库中的内容。正如deviantfan所建议的,我一定要阅读socket comm通信。如果我不这样做,我想情况会比现在更糟。你声称OP不需要sendbuffer是不正确的,在选择的逻辑中,他确实需要那个缓冲。@slava:这不是我的经验:sendString.c_str()
可以直接使用。这并不矛盾。有任何参考资料吗?@stefaanv问题不在于c_str()
是否可以直接使用。问题是OP选择始终发送1023字节(零填充),所以如果字符串长度小于他不能使用的c_str()
直接。@slava:我认为这是一个错误。由他来决定。
void sendBuffer( const char *buff, size_t size )
{
for( size_t sent = 0; sent != size; ) {
int rc = send( socket, buff + sent, size - sent );
if( rc <= 0 ) { // handle error here
}
sent += static_cast<size_t>( rc );
}
}
uint32_t size = str.length();
sendBuffer( reinterpret_cast<char *>( &size ), sizeof( size ) );
sendBuffer( str.data(), size );