Autor Wątek: SDL_net i localhost  (Przeczytany 1114 razy)

Offline mawpa

  • Użytkownik

# Czerwiec 14, 2015, 22:46:55
Napisałem sobie klasę, która w założeniu ma być prostym w użyciu wrapperem na domyślne SDLowe funkcje:
class Device
{
protected:
  IPaddress ip;
  UDPsocket socket;
  UDPpacket* packet;

  static const short buffer_size = 512;
  static const short port = 1337;

public:
  enum Mode
  {
    Server,
    Client,
    Dummy // used only for sending messages
  };

  Device(Mode mode, const char* remote_ip = nullptr)
  {
    if(mode == Server)
      socket = SDLNet_UDP_Open(port);
    else
    {
      if(mode == Dummy && remote_ip != nullptr)
        SDLNet_ResolveHost(&ip, remote_ip, port);
      else
        socket = SDLNet_UDP_Open(0);
    }

    packet = SDLNet_AllocPacket(buffer_size);
  }

  virtual ~Device() {
     SDLNet_FreePacket(packet);
  }

  bool receive() {
    return (SDLNet_UDP_Recv(socket, packet) != 0);
  }

  std::string message() {
    return std::string((char*)packet->data);
  }

  IPaddress sender() {
    return packet->address;
  }

  void send(Device* recipient, std::string message)
  {
    packet->address = recipient->ip;
    packet->data = (Uint8*)message.c_str();
    packet->len = message.length();
    packet->status = 0;

    SDLNet_UDP_Send(recipient->socket, -1, packet);
  }
};

W programie serwera mam dwa obiekty (oczywiście najpierw robię SDLNet_Init()):
Device serv(Device::Server);
Device client(Device::Dummy);

I w pętli w założeniu "odbijam" wiadomości do adresata:
if(serv.receive())
{
  client.setIP(serv.sender());
  serv.send(&client, serv.message());
}

W kliencie też mam dwa obiekty:
Device serv(Device::Dummy, "localhost");
Device client(Device::Client);

I w pętli po prostu zbieram input, który wysyłam do serwera. Jeśli coś odbije, to to wyświetlam.

Problem: odpalam serwer na localhoście, odpalam klienta na localhoście, piszę coś i serwer tego nie otrzymuje. Szukałem w Google i wydaje mi się, że ludziom działa podobne rozwiązanie. Próbowałem wszystkiego, co przyszło mi do głowy (stąd taki, a nie inny konstruktor :P ). Pewnie gdzieś zrobiłem jakiś idiotyczny błąd, ale nie potrafię go znaleźć. Możecie mi pomóc?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Xion

  • Redaktor
    • xion.log

# Czerwiec 14, 2015, 23:39:00
Sprawdzałeś chociaż czy te pakiety są wysyłane i czy wyglądają sensownie, np. jakimś Wiresharkiem?

Offline mawpa

  • Użytkownik

# Czerwiec 15, 2015, 00:45:42
Już złapałem buga. Wystarczyło zmienić konstruktor na taki:

Device::Device(Mode mode, const char* remote_ip)
{
  if(mode == Server)
  {
    socket = SDLNet_UDP_Open(port);
    packet = SDLNet_AllocPacket(buffer_size);
  }
  else if(mode == Client)
  {
    socket = SDLNet_UDP_Open(0);
    packet = SDLNet_AllocPacket(buffer_size);
  }
  else if(remote_ip != nullptr)
    SDLNet_ResolveHost(&ip, remote_ip, port);
}

A pole socket ustawić jako static. Będę z tym kombinował, żeby było bardziej elegancko, ale działa.