为啥我没有收到来自服务器的消息?

Posted

技术标签:

【中文标题】为啥我没有收到来自服务器的消息?【英文标题】:Why am I not receiving messages from the server?为什么我没有收到来自服务器的消息? 【发布时间】:2021-12-20 18:12:09 【问题描述】:

我正在尝试按照官方文档连接到 twitch:https://dev.twitch.tv/docs 但我无法连接,每个函数都返回成功,但我仍然没有在while(1) 循环内收到任何消息。

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

BOOL WriteServerMessage(SOCKET s, const char *msg)

    printf("Sending \"%s\"...", msg);
    INT ret = send(s, msg, strlen(msg), 0);
    if(ret < 0)
    
        printf(" error %lu\n", GetLastError());
        return 0;
    
    printf(" success!\n");
    return 1;


int main(int argc, char **argv)

    WSADATA wsaData;
    INT iRetval;

    struct addrinfo *result = NULL;
    struct addrinfo hints;

    struct sockaddr_in *sockaddr_ipv4;

    iRetval = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if(iRetval != 0)
    
        printf("WSAStartup failed: %d\n", iRetval);
        return 1;
    

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    iRetval = getaddrinfo(argv[1], argv[2], &hints, &result);
    if(iRetval != 0)
    
        printf("getaddrinfo failed with error: %d\n", iRetval);
        WSACleanup();
        return 1;
    
    sockaddr_ipv4 = (struct sockaddr_in*) result->ai_addr;

    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    iRetval = connect(sock, (struct sockaddr*) sockaddr_ipv4, sizeof(*sockaddr_ipv4));
    if(iRetval < 0)
    
        printf("Bind failed with %u\n", WSAGetLastError());
        printf("Server port: %d\n", sockaddr_ipv4->sin_port);
    
    WriteServerMessage(sock, "PASS oauth:hbptkiz0ot187euawbnnkvghdhdgk3");
    WriteServerMessage(sock, "NICK kanalmanagerbot");
    WriteServerMessage(sock, "JOIN #h0llylp");
    WriteServerMessage(sock, "PRIVMSG #h0llylp :Hello there");
    char buf[1024];
    while(1)
    
        if(recv(sock, buf, sizeof(buf), 0) > 0)
        
            printf("Received: %s\n", buf);
            if(!strcmp(buf, "PING :tmi.twitch.tv"))
                WriteServerMessage(sock, "PONG :tmi.twitch.tv");
        
        Sleep(10);
    
    WriteServerMessage(sock, "PART #h0llylp");
    WriteServerMessage(sock, "QUIT");

    closesocket(sock);

    freeaddrinfo(result);
    WSACleanup();
    return 0;

我正在调用带有这些标志的 .exe:“irc.chat.twitch.tv”6667

我正在使用JOIN 加入随机聊天,oauth 令牌是在此处生成的:https://twitchapps.com/tmi/#access_token

我希望能够加入聊天并使用所有 IRC 功能,例如 NAMESPRIVMSG

我做错了什么?

【问题讨论】:

在函数WriteServerMessage中,语句if(ret &lt; 0)检查send是否失败,但它不验证它是否完全成功。它可能只是部分成功。你应该改写if ( ret != strlen(msg) ) @AndreasWenzel 我更改了支票,但仍然打印成功。 一方面,您的消息不会以换行符终止。 @AKX 哦,解决了。为什么它是必要的?可能是服务器分批收集消息,然后在新行拆分它们? 查看我的回答了解详情。无论如何,TCP 是一个面向流的协议;如果没有应用程序协议,接收端就无法知道单个“消息”是什么。 【参考方案1】:

Twitch IRC guide 表示他们“通常关注RFC1459”。

该文档依次says

IRC 消息总是以 CR-LF(回车 - 换行)对结尾的字符行,这些消息的长度不得超过 512 个字符,包括尾随 CR-LF 在内的所有字符。

您发送的消息字符串不会被 CR-LF 终止,因此在您发送 CR-LF 之前服务器不会对它们进行任何处理。

您需要确保根据规范正确终止您的消息。

您的套接字读取代码也需要适应这一点 - 您不能只读取多个字节并希望它们完全是一条消息。

【讨论】:

以上是关于为啥我没有收到来自服务器的消息?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我无法在 Android 设备上接收来自 GCM 的消息

为啥我在我的设备上收到成功注册消息,而服务器数据库没有变化?

为啥 ZeroMQ 服务器没有收到来自客户端的任何请求?

为啥我的消息消费者没有收到所有其他消息?

为啥我在本地环境(而在原始服务器上没有)上的 Wordpress 博客文章(仅)上收到错误消息

为啥我的 XMPP 客户端重新发送消息?