我正在尝试使用UDP和SDL_Net 2库编写一个简单的回显服务器。
服务器收到该数据包的罚款,并尝试将其发送回它来自的地址,但是客户端什么也没收到。

这是我的服务器代码(减去一些不相关的部分,这些部分已被删除):

void main()
{
    /* variables */

    if(!(sd = SDLNet_UDP_Open(2000)))
    {
        printf("Could not create socket\n");
        SDLNet_Quit();
        exit(1);
    }

    if(!(p = SDLNet_AllocPacket(512)))
    {
        printf("Could not allocate packet\n");
        SDLNet_Quit();
        exit(2);
    }

    quit = 0;
    while(!quit)
    {
        if(SDLNet_UDP_Recv(sd, p))
        {
            printf("%s\n", (char*)p->data);
            printf("\tFrom port: %d\n", p->address.port);

            UDPsocket socket = SDLNet_UDP_Open(0);
            if(!socket)
            {
        printf("Could not create socket to send\n");
            }
            else
            {
                printf("\tSending packet\n");
                UDPpacket* send = SDLNet_AllocPacket(512);
                if(!send)
                {
                    printf("Could not allocate packet to send\n");
                }
                else
                {
                    send->address = p->address;
                    send->channel = -1;
                    send->data = (char*)p->data;
                    send->len = strlen((char*)send->data) + 1;
                    send->status = 0;
                    SDLNet_UDP_Send(socket, -1, send);
                }
            }
        }
    }

    /* cleanup */
}


因此,在服务器端,我基本上在端口2000上侦听传入的数据包,然后在接收到一个数据包时将其发送回去。

这是客户的代码(同样,去除了某些部分):

void main()
{
    SDLNet_Init();

    if(!(sd = SDLNet_UDP_Open(0)))
    {
        printf("Could not create socket\n");
        SDLNet_Quit();
        SDL_Quit();
        exit(1);
    }

    IPaddress* myaddress = SDLNet_UDP_GetPeerAddress(sd, -1);
    if(!myaddress)
    {
        printf("Could not get own port\n");
        exit(2);
    }
    printf("My port: %d\n", myaddress->port);
    UDPpacket* recvp = SDLNet_AllocPacket(512);
    if(!recvp)
    {
        printf("Could not allocate receiving packet\n");
        exit(3);
    }

    UDPsocket socket;
    socket = SDLNet_UDP_Open(myaddress->port);
    if(!socket)
    {
        printf("Could not allocate receiving socket\n");
        exit(4);
    }

    // resolve server host
    SDLNet_ResolveHost(&srvadd, "localhost", 2000);

    if(!(p = SDLNet_AllocPacket(512)))
    {
        printf("Could not allocate packet\n");
        SDLNet_Quit();
        SDL_Quit();
        exit(2);
    }

    p->address.host = srvadd.host;
    p->address.port = srvadd.port;

    /* ... */
    while(run)
    {
        if(SDLNet_UDP_Recv(socket, recvp))
        {
            printf("Receiving packet\n");
            char* data = (char*)recvp->data;
            if(strcmp(data, "left") == 0)
            {
                printf("received left\n");
            }
        }

        SDL_Event e;
        while(SDL_PollEvent(&e))
        {
            if(e.type == SDL_KEYDOWN)
            {
                switch(e.key.keysym.sym)
                {
                    case SDLK_LEFT:
                        p->data = "left";
                        p->len = strlen("left") + 1;
                        SDLNet_UDP_Send(sd, -1, p);
                        break;
                    case SDLK_RIGHT:
                        p->data = "right";
                        p->len = strlen("right") + 1;
                        SDLNet_UDP_Send(sd, -1, p);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    /* cleanup */
}


因此,客户端发送到达服务器的数据包,并且同时侦听(但从没听到任何消息)。请注意,这些都是非阻塞调用。

我需要做些额外的事情吗?难道我做错了什么?

最佳答案

我认为问题是您第一次发送时设置p.address的方式。在文档中指出,SDLNet_ResolveHost以网络字节顺序(而不是本机顺序)返回IP地址,因此可以将其从表示127.0.0.1的整数更改为相反的值:1.0.0.127。

您可以看到它进行了快速调试。希望这可以帮助。另外,文档不是很精确,因为使用的是网络顺序或本机顺序,而且我不是SDLNet方面的专家。

07-27 18:47