Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.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+中接收到垃圾值+;_C++_Windows_Sockets - Fatal编程技术网

C++ 在客户端-服务器通信c+中接收到垃圾值+;

C++ 在客户端-服务器通信c+中接收到垃圾值+;,c++,windows,sockets,C++,Windows,Sockets,我试图在windows上编写一个简单的客户机-服务器程序。我的服务器端代码如下所示 #include <iostream> #include <windows.h> #include <winsock2.h> #include <stdlib.h> #include <stdio.h> using namespace std; int main() { WSADATA WSAData; SOCKET serverSo

我试图在windows上编写一个简单的客户机-服务器程序。我的服务器端代码如下所示

#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>

using namespace std;

int main()
{
    WSADATA WSAData;
    SOCKET serverSock, clientSock;
    SOCKADDR_IN serverAddr, clientAddr;

    WSAStartup(MAKEWORD(2,0),&WSAData);
    serverSock=socket(AF_INET,SOCK_STREAM,0);

    serverAddr.sin_addr.s_addr=INADDR_ANY;
    serverAddr.sin_family=AF_INET;
    serverAddr.sin_port=htons(5555);

    bind(serverSock,(SOCKADDR *)&serverAddr, sizeof(serverAddr));
    listen(serverSock,0);
    std::cout<<"Listening for incoming connections \n";

    char buffer[1024];
    //memset(buffer,0,sizeof(buffer));
    int clientAddrsize= sizeof(clientAddr);
    if(clientSock = ( accept(serverSock,(SOCKADDR *)&clientAddr, &clientAddrsize ) != INVALID_SOCKET) )
    {
        std::cout<<"Client connected \n";
        recv(clientSock,buffer,int(strlen(buffer)),0);
        std::cout<<"Client Says: " << buffer <<"\n" ;
        Sleep(10000);
        //memset(buffer,0,sizeof(buffer));
        closesocket(clientSock);
        closesocket(serverSock);
        WSACleanup();
    }
    return 0;
}
我所期待的是
客户说:你好。
。不知道为什么我会得到垃圾值

谢谢

这将在自动作用域中声明一个本地
char
数组。数组没有初始化任何内容,并且包含随机垃圾

recv(clientSock,buffer,int(strlen(buffer)),0);
这将
缓冲区
传递到
strlen
。然而,
buffer
包含垃圾,这是未定义的行为,最终的结果可能是,随机的,立即崩溃,在这一点上,或者从
strlen
返回一些奇怪的值

此外,
recv
的返回值完全被忽略,根本不检查

所有套接字系统调用都可能失败,每个套接字系统调用、
send
recv
,以及所有其他调用都可能失败。此外,即使成功,
recv
也不能保证一次发送的所有内容都将在一次发送中
recv
ed

例如,如果
send
sent 10个字节,则对
recv
的第一次调用可能返回1或5,这表示只有前一个或五个字节立即被
recv
ed。您不能保证
recv
会一次全部接收到这10个字节。否则,
recv
显然需要再次调用以接收消息的其余部分

为了拥有可靠的客户机/服务器应用程序,您需要解决所有这些问题:

  • 检查所有系统调用的返回值。关于
    recv
    我所说的一切也适用于
    send
    。尝试
    send
    10个字节可能返回7个字节,这表示只发送了前7个字节,然后您必须实现适当的逻辑来发送剩余的字节

  • 修复未定义的行为,将未初始化的值传递给strlen


  • “垃圾”值几乎总是依赖于使用未初始化的数据(局部变量或数组元素);或者不添加、跳过或不计算字符串空终止符与字符缓冲区[1024]=“您好。”您需要始终捕获recv()返回的值并对其进行适当的操作。如果不知道,则无法知道recv()实际写入本地缓冲区的字节数。(可能比您请求的字节少)例如:
    send(clientSock,buffer,int(strlen(buffer)),0)
    不会发送
    缓冲区的空终止符
    。和
    recv(clientSock,buffer,int(strlen(buffer)),0)
    使用
    缓冲区的未初始化内容(因此不确定,如果您愿意,也可以使用垃圾)来计算数组的大小。因此,我前面列出的两个问题都存在。另外,将strlen(buffer)作为最后一个参数传递给recv()没有多大意义,因为strlen()读取其参数指向的字节以查看字符串的长度,而在调用recv()时,字符串尚未收到,因此这是不可能的。您可能希望传递sizeof(缓冲区)。感谢@Sam提供详细信息。非常感谢。你能告诉我一些关于这个的实际实现吗?在这里,我可以看到关于如何处理由brotobuf序列化并发送的数据的参考代码。或者任何有意义的数据交换示例,这样我就可以从中吸取教训,或者给我指一个教程。在互联网上,大多数人没有显示如何正确处理和读取TCP数据包。我同意:不能从C语言、C++或任何技术编程主题中找到随机数据,或者一些小丑上传到YouTube的随机视频。学习高级技术主题的唯一方法是借助好的教科书。经典的教科书是史蒂文斯的《Unix网络编程》,但我认为它到现在已经有点过时了。但是,如果你搜索这本书,你应该找到一些其他相当好的书作为参考。
    
     Listening for incoming connections
     Client connected
     Client Says: R☺
    
    char buffer[1024];
    
    recv(clientSock,buffer,int(strlen(buffer)),0);