Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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_Tcp - Fatal编程技术网

C++ 套接字发送()在发送一定数量的字节后挂起

C++ 套接字发送()在发送一定数量的字节后挂起,c++,sockets,tcp,C++,Sockets,Tcp,我想向我的nodejs TCP服务器发送一个字符串 这是我的客户机(C++)的代码: 问题来了: 客户端只发送大约180条消息,然后send挂起。服务器仅接收约120条消息。当我增加请求的长度时,客户端发送的请求较少,而当我减少请求的长度时,客户端发送的请求较多。我还发现,当我减少发送间隔时,我可以在send挂起之前发送更多请求。我不知道我做错了什么。当我用NoDEJS客户端执行类似的代码时,一切都正常,所以问题在于C++客户端。 编辑: 我并不认为这是必要的,但下面是connectToServ

我想向我的nodejs TCP服务器发送一个字符串

这是我的客户机(C++)的代码:

问题来了:

客户端只发送大约180条消息,然后
send
挂起。服务器仅接收约120条消息。当我增加请求的长度时,客户端发送的请求较少,而当我减少请求的长度时,客户端发送的请求较多。我还发现,当我减少发送间隔时,我可以在
send
挂起之前发送更多请求。我不知道我做错了什么。当我用NoDEJS客户端执行类似的代码时,一切都正常,所以问题在于C++客户端。 编辑:

我并不认为这是必要的,但下面是
connectToServer()的代码

< > C++客户端输出(发送间隔:2000毫秒,MSGLIGH:126~127字符):

来自nodejs服务器的输出(仅接收9条消息):

测试结果以查看发送间隔、消息长度和发送消息数之间是否存在连接:

connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678900

...keeps going on for a while...

connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678909
sendInterval | msgLength | nMsg --------------------------------------- 200 | 127 | 26 200 | 65 | 33 --------------------------------------- 400 | 65 | 59 400 | 127 | 53 --------------------------------------- 2000 | 65 | 47 2000 | 127 | 21 发送间隔| msgLength | nMsg --------------------------------------- 200 | 127 | 26 200 | 65 | 33 --------------------------------------- 400 | 65 | 59 400 | 127 | 53 --------------------------------------- 2000 | 65 | 47 2000 | 127 | 21
(我看不出这些值之间有什么联系)

正如我所见,您应该注意一些问题:

  • 您正试图将许多消息发送到客户的 代码,但使用 变量
    sendResult
    。在发送另一个之前,应该检查它 信息
  • 您使用同一个线程发送数据并检查发送每条消息的时间间隔,这会消耗大量CPU。我建议创建一个线程(TSync)来参加
    sleep
    std::chrono
    的间隔,并调用一个通过套接字发送消息的方法,但不在同一个线程TSync中,因为您将使用sleeps阻塞套接字
  • 最后,您应该使用
    FD_SET
    select
    检查何时可以通过套接字发送数据,何时套接字可以发送更多字节
  • 可能是您在没有控制的情况下发送消息的方式影响了TX通道,因为TX通道已满,因此您应该使用
    FD_SET
    控制输出操作,并选择
    以与套接字同步。在write的情况下,表示:

    选择功能用于确定一个或多个套接字的状态。对于每个套接字,调用方可以请求有关读取、写入或错误状态的信息

    writefds:可以发送数据

    更新,4月21日:我建议您分享有关您的问题的更多信息,如服务器的代码和配置,以了解是否存在超时配置或缓冲区大小。提供给您的信息不够,并且不要低估我们向您提出的请求,如以下评论:

    我并不认为这是必要的,但下面是connectToServer()的代码:

    连接过程很重要,因为我们可以看到套接字服务器是否设置了一些选项

    在这种情况下,您与我们共享的所有信息都会有所帮助,而不是假设这些信息并不重要

    所以,在这个时刻,这就是我能帮助你的全部

    4月24日更新:尝试以下步骤控制套接字传输并设置非阻塞套接字:

    • 成功连接后,在客户端中,将套接字设置为非阻塞

    • 使用循环文件描述符(
      FD_SET
      )和
      选择来检查套接字何时准备好写入

    您的代码应包含以下代码:

    void ConnectToServer()
    {
        //... your code
    
        int connectResult = ::connect(sock, (struct sockaddr *)&server, sizeof(server));
        if (connectResult >= 0)
        {
            u_long iMode = 1;
            int iResult = ioctlsocket(sock, FIONBIO, &iMode); //Set the socket Non-Blocking
    
            printf("Connected to server!\n");
        }
        else
        {
            printf("Not connected to server. Err: %d\n", connectResult);
        }
    }
    
    int main(){
        Connect(); //function to connect with a WiFi network
        ConnectToServer();
    
        unsigned long lastSendTime = 0;
        unsigned long sendInterval = 200; //send a message every 200 milliseconds
        unsigned int nMsgSent = 0;
    
    
        fd_set write_fd;
    
        while (1){
            unsigned long now = milliseconds(); //function to get the time in milliseconds
            if ((now - lastSendTime) > sendInterval){
                std::string request = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
                request += request;
                request += std::to_string(nMsgSent);
                request += "\n";
    
                FD_ZERO(&write_fd); //Reset the File Descriptor
                FD_SET(sock, &write_fd); //Set se File descriptor to the socket.
    
                int result = select(max_sd, NULL, &write_fd, NULL, NULL);   //Wait until the socket is ready to write
    
                if (result < 0)
                {
                    iprintf("There was a problem with the sockets reading.\n");
                    FD_ZERO(&write_fd);
                }
    
                int sendResult = ::send(sock, request.c_str(), request.length(), 0);
                iprintf("req(%d): %d\n", nMsgSent, sendResult);
    
                nMsgSent++;
                lastSendTime = now;
            }
        }
        return 0;
    }
    
    void ConnectToServer()
    {
    //…您的代码
    int connectResult=::connect(sock,(struct sockaddr*)和server,sizeof(server));
    如果(连接结果>=0)
    {
    u_long iMode=1;
    int-iResult=ioctlsocket(sock、FIONBIO和iMode);//将套接字设置为非阻塞
    printf(“已连接到服务器!\n”);
    }
    其他的
    {
    printf(“未连接到服务器。错误:%d\n”,connectResult);
    }
    }
    int main(){
    Connect();//用于连接WiFi网络的函数
    ConnectToServer();
    无符号长lastSendTime=0;
    unsigned long sendInterval=200;//每200毫秒发送一条消息
    无符号整数nMsgSent=0;
    fd_集写_fd;
    而(1){
    unsigned long now=毫秒();//函数以毫秒为单位获取时间
    如果((现在-上次发送时间)>发送间隔){
    std::string request=“abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz1234567890”;
    请求+=请求;
    请求+=std::to_字符串(nMsgSent);
    请求+=“\n”;
    FD_ZERO(&write_FD);//重置文件描述符
    FD_SET(sock,&write_FD);//将se文件描述符设置为套接字。
    int result=select(max_sd,NULL,&write_fd,NULL,NULL);//等待套接字准备好写入
    如果(结果<0)
    {
    iprintf(“套接字读取有问题。\n”);
    FD_ZERO(&write_FD);
    }
    int sendResult=::发送(sock,request.c_str(),request.length(),0);
    iprintf(“请求(%d):%d\n”、nMsgSent、sendResult);
    nMsgSent++;
    lastSendTime=现在;
    }
    }
    返回0;
    }
    
    不要发送垃圾标签!这不是C。C不是C++不是C!@Olaf我知道,但套接字库是C代码,对吗?@user7353781套接字库的语言与您的问题无关。如果客户端发送消息的速度快于服务器读取消息的速度,则clie
    req(1): 126
    req(2: 126
    req(3): 126
    ...keeps going on for a while...
    req(9): 126
    req(10): 126
    req(11): 127
    req(12): 127
    ...keeps going on for a while...
    req(74): 64
    send() hangs after this
    
    connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678900
    
    ...keeps going on for a while...
    
    connection data from ip::port: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678909
    
    sendInterval | msgLength | nMsg --------------------------------------- 200 | 127 | 26 200 | 65 | 33 --------------------------------------- 400 | 65 | 59 400 | 127 | 53 --------------------------------------- 2000 | 65 | 47 2000 | 127 | 21
    void ConnectToServer()
    {
        //... your code
    
        int connectResult = ::connect(sock, (struct sockaddr *)&server, sizeof(server));
        if (connectResult >= 0)
        {
            u_long iMode = 1;
            int iResult = ioctlsocket(sock, FIONBIO, &iMode); //Set the socket Non-Blocking
    
            printf("Connected to server!\n");
        }
        else
        {
            printf("Not connected to server. Err: %d\n", connectResult);
        }
    }
    
    int main(){
        Connect(); //function to connect with a WiFi network
        ConnectToServer();
    
        unsigned long lastSendTime = 0;
        unsigned long sendInterval = 200; //send a message every 200 milliseconds
        unsigned int nMsgSent = 0;
    
    
        fd_set write_fd;
    
        while (1){
            unsigned long now = milliseconds(); //function to get the time in milliseconds
            if ((now - lastSendTime) > sendInterval){
                std::string request = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
                request += request;
                request += std::to_string(nMsgSent);
                request += "\n";
    
                FD_ZERO(&write_fd); //Reset the File Descriptor
                FD_SET(sock, &write_fd); //Set se File descriptor to the socket.
    
                int result = select(max_sd, NULL, &write_fd, NULL, NULL);   //Wait until the socket is ready to write
    
                if (result < 0)
                {
                    iprintf("There was a problem with the sockets reading.\n");
                    FD_ZERO(&write_fd);
                }
    
                int sendResult = ::send(sock, request.c_str(), request.length(), 0);
                iprintf("req(%d): %d\n", nMsgSent, sendResult);
    
                nMsgSent++;
                lastSendTime = now;
            }
        }
        return 0;
    }