RaptorDotCpp
RaptorDotCpp

Reputation: 1475

UDP Echo server not receiving on client

I'm trying to write a simple echo server with UDP and the SDL_Net 2 library. The server receives the packet fine and tries to send one back to the address where it came from, but the client doesn't receive anything.

Here is my server code (minus some irrelevant parts that have been stripped out):

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

So on the server side, I basically listen for incoming packets on port 2000 and then send a packet back on receiving one.

This is the client's code (again, with some parts stripped out):

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

So the client sends packet, which arrive at the server, and also listens at the same time (but never hears anything). Note that these are all non blocking calls.

Do I need to do something extra? Am I doing something wrong?

Upvotes: 0

Views: 1402

Answers (2)

jsaak
jsaak

Reputation: 645

You are doing a lot of things wrong. I wrote a simple server:

#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;
}

You can test it with: $ nc -u localhost 3333

Upvotes: 0

dsob
dsob

Reputation: 11

I think the problem is the way you set p.address at first sending. It is stated in the docs that SDLNet_ResolveHost returns an IPaddress in network byte order, not native order, so it may be changed from an integer representing 127.0.0.1 to the opposite: 1.0.0.127.

You can see it making a quick debug. Hope this helps. Also the docs are not very precise as where network order or native order are used, and i am not that expert on SDLNet.

Upvotes: 1

Related Questions