Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这些通过套接字发送/接收字符串的函数有什么问题?_C++_Sockets - Fatal编程技术网

C++ 这些通过套接字发送/接收字符串的函数有什么问题?

C++ 这些通过套接字发送/接收字符串的函数有什么问题?,c++,sockets,C++,Sockets,我正在尝试编写两种通过套接字发送和接收字符串的方法。这是为了清理Windows的遗留代码,它使用了散布在各处的send和recv,因此我想让它发挥作用来清理一下。你可以在下面看到我的想法。不幸的是,当我在代码中像这样使用函数时: std::string buffer = receiveStringFromSocket(); 及 我的代码被锁定,甚至不再达到断点 谁能告诉我我做错了什么?我很难调试它,因为我对C/C++不是很熟悉。这可能是错误在混乱的代码库中的其他地方 发送StringToSoc

我正在尝试编写两种通过套接字发送和接收字符串的方法。这是为了清理Windows的遗留代码,它使用了散布在各处的
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 );