首页 文章

UDP Echo服务器未在客户端上接收

提问于
浏览
0

我正在尝试用UDP和SDL_Net 2库编写一个简单的echo服务器 . 服务器接收数据包并尝试将其发送回它来自的地址,但客户端没有收到任何信息 .

这是我的服务器代码(减去一些已被剥离的无关部分):

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 */
}

因此,客户端发送到达服务器的数据包,并同时监听(但从不听任何事情) . 请注意,这些都是非阻塞调用 .

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

2 回答

  • 1

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

    你可以看到它进行快速调试 . 希望这可以帮助 . 此外,文档不是非常精确,因为使用网络订单或本机订单,我不是SDLNet的专家 .

  • 0

    你做了很多错事 . 我写了一个简单的服务器:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <arpa/inet.h>
    
    #include "SDL_net.h"
    
    main(int argc, char *argv[]) {
        IPaddress serverIP;
        UDPsocket udpsock;
        UDPpacket* recv_packet;
        SDLNet_SocketSet socketset = NULL;
        int numused;
        static const int MAX_PACKET_SIZE = 512;
    
        if (SDLNet_Init() < 0) {
          printf("Couldn't initialize net: %s\n", SDLNet_GetError());
          exit(1);
        }
    
        udpsock = SDLNet_UDP_Open(3333);
        if(!udpsock) {
          printf("SDLNet_UDP_Open: %s\n", SDLNet_GetError());
          exit(2);
        } else {
          printf("listening on 0.0.0.0:3333\n");
        }
    
        socketset = SDLNet_AllocSocketSet(2);
        if ( socketset == NULL ) {
          fprintf(stderr, "Couldn't create socket set: %s\n", SDLNet_GetError());
          exit(2);
        }
    
        numused = SDLNet_UDP_AddSocket(socketset,udpsock);
        if(numused==-1) {
          printf("SDLNet_AddSocket: %s\n", SDLNet_GetError());
          exit(2);
        }
    
        recv_packet = SDLNet_AllocPacket(MAX_PACKET_SIZE);
        if(!recv_packet) {
          printf("Could not allocate packet\n");
          exit(2);
        }
    
        while(1) {
          SDLNet_CheckSockets(socketset, ~0);
          if (SDLNet_SocketReady(udpsock)) {
            if (SDLNet_UDP_Recv(udpsock, recv_packet)) {
              SDLNet_UDP_Send(udpsock, -1, recv_packet);
    
              //format log
              int len = recv_packet->len;
              char temp[MAX_PACKET_SIZE+2];
              memcpy(temp, recv_packet->data, len);
    
              if (temp[len-1] == '\n') {
               temp[len-1] = '\\';
               temp[len] = 'n';
               temp[len+1] = '\0';
              } else {
               temp[len] = '\0';
              }
    
              char hoststring[128];
              inet_ntop(AF_INET,&recv_packet->address.host,hoststring,128),
    
              printf("got: \"%s\" from: %s:%d\n",
                  temp,
                  hoststring,
                  ntohs(recv_packet->address.port));
            }
          }
        }
        return 0;
    }
    

    你可以测试它: $ nc -u localhost 3333

相关问题