Add a "SafeUDPpacket" and "SafeUDPpacketV" class.

I'm trying to merge UDPpacketVBuffer and SafeUDPpacketV.

Seems pretty messy so far... hopefully this is fruitful.
This commit is contained in:
Bubblegumdrop 2022-01-16 14:40:20 -05:00
parent dcbd011582
commit 60e282929f
15 changed files with 500 additions and 243 deletions

View File

@ -1,4 +1,4 @@
.PHONY: all clean
.PHONY: all clean reallyclean test
.POSIX:
# {{{ Flags
@ -27,6 +27,7 @@ OBJS := $(patsubst %,$(OBJDIR)/%.o,$(basename $(SRCS)))
DEPS := $(patsubst %,$(DEPDIR)/%.d,$(basename $(SRCS)))
COMMON_OBJS := \
$(OBJDIR)/src/lib_GetOpt.o \
$(OBJDIR)/src/lib_lua_common.o \
$(OBJDIR)/src/lib_SDL_common.o \
$(OBJDIR)/src/lib_SDL_Log.o \
@ -186,9 +187,13 @@ $(OBJDIR)/%.o: %.cxx $(DEPDIR)/%.d
$(COMPILE.cc) $<
$(POSTCOMPILE)
clean: REALLYCLEAN?=@echo
clean:
@echo $(RM) $(DEPDIR) $(OBJDIR) $(PROGS)
@echo $(RM) $(TEST_PROGS)
$(REALLYCLEAN) $(RM) $(DEPDIR) $(OBJDIR) $(PROGS)
$(REALLYCLEAN) $(RM) $(TEST_PROGS)
reallyclean:
$(MAKE) REALLYCLEAN= clean
.PRECIOUS: $(DEPDIR)/%.d
$(DEPDIR)/%.d: ;

99
include/SafeUDPpacket.h Normal file
View File

@ -0,0 +1,99 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <SDL_assert.h>
#include <SDL_net.h>
class SafeUDPpacket
{
struct SDLNet_PacketDeleter
{
void operator () (UDPpacket* p)
{
SDLNet_FreePacket (p);
p = NULL;
}
};
std::unique_ptr<UDPpacket, SDLNet_PacketDeleter> m_packet;
void Reset (UDPpacket* p)
{
m_packet.reset (p);
}
public:
SafeUDPpacket (int size)
{
UDPpacket* p;
if (NULL == (p = SDLNet_AllocPacket (size)))
{
throw "SDLNet_AllocPacket: " + std::string (SDLNet_GetError ());
}
Reset (p);
}
SafeUDPpacket (UDPpacket* p)
{
Reset (p);
}
UDPpacket* get (void) const
{
return m_packet.get ();
}
int channel (int channel) const { return get()->channel = channel; }
int channel (void) const { return get()->channel; }
int len (int len) const { return get()->len = len; }
int len (void) const { return get()->len; }
int maxlen (int maxlen) const { return get()->maxlen = maxlen; }
int maxlen (void) const { return get()->maxlen; }
int status (int status) const { return get()->status = status; }
int status (void) const { return get()->status; }
IPaddress address (IPaddress address) const { return get()->address = address; }
IPaddress address (void) const { return get()->address; }
Uint8 *data (Uint8* data) const { return get()->data = data; }
Uint8 *data (void) const { return get()->data; }
};
class SafeUDPpacketV
{
std::vector<SafeUDPpacket> m_packetV;
public:
SafeUDPpacketV (const void*, const int, const int mtu = 1450);
SafeUDPpacketV (int howmany, int size)
{
UDPpacket** p;
m_packetV.reserve (howmany);
if (NULL == (p = SDLNet_AllocPacketV (howmany, size)))
{
throw "SDLNet_AllocPacketV: " + std::string (SDLNet_GetError ());
}
else
{
for (; (p != NULL) && (*p != NULL); p++)
{
m_packetV.push_back (SafeUDPpacket (*p));
}
SDL_assert ((m_packetV.size () > 0) && (howmany == (int)m_packetV.size ()));
/*
* SDLNet_FreePacketV just calls SDLNet_FreePacket on each packet.
* The "packetV" itself is just something allocated on the heap.
* We don't need this any longer.
*/
SDL_free (p);
}
}
const SafeUDPpacket& get (size_t idx)
{
return m_packetV.at (idx);
}
size_t size (void) const
{
return m_packetV.size ();
}
std::string toString (void);
};

View File

@ -6,6 +6,9 @@
#include "lib_lua_common.h"
#include "UDPbase.h"
/*
* Used as mFetchPacketsCallbackTimerID timeout
*/
#define DEFAULT_SOCKET_TIMEOUT 10
class Server : public UDPbase

View File

@ -5,32 +5,53 @@
#include <SDL_net.h>
#define DEFAULT_MAX_PACKET_SIZE 250
#define DEFAULT_MAX_PACKET_SIZE 512
class UDPbase
class
UDPbase
{
int mChannel;
IPaddress mIPAddress;
void
CloseAllSockets (void);
protected:
std::vector<UDPsocket> UDPsocks;
public:
UDPbase (const char* host, const Uint16 port);
UDPbase (const char* host, const Uint16 port, const int channel);
UDPbase (const char *host, const Uint16 port);
UDPbase (const char *host, const Uint16 port, const int channel);
~UDPbase (void);
int ResolveHost (IPaddress*, const char*, const Uint16);
int
ResolveHost (IPaddress *, const char *, const Uint16);
UDPsocket UDP_Open (void);
UDPsocket UDP_Open (const Uint16 port);
void UDP_Close (UDPsocket sock);
int UDP_Bind (UDPsocket sock, const int channel);
void UDP_Unbind (UDPsocket sock, const int channel);
IPaddress* UDP_GetPeerAddress (UDPsocket sock, const int channel);
UDPsocket
UDP_Open (void);
UDPsocket
UDP_Open (const Uint16 port);
void
UDP_Close (UDPsocket sock);
int
UDP_Bind (UDPsocket sock, const int channel);
void
UDP_Unbind (UDPsocket sock, const int channel);
IPaddress *
UDP_GetPeerAddress (UDPsocket sock, const int channel);
void CloseAllSockets (void);
int
getChannel (void) const
{
return
mChannel;
}
UDPsocket
getSocket (const size_t idx) const
{
return
UDPsocks.
at (idx);
}
int getChannel (void) const { return mChannel; }
UDPsocket getSocket (const size_t idx) const { return UDPsocks.at (idx); }
std::string toString (void);
std::string
toString (void);
};

View File

@ -1,5 +1,6 @@
#pragma once
#include <string>
#include <SDL_net.h>
/**
@ -36,25 +37,26 @@ Then free the leftover setup packet:
*/
class UDPpacketVBuffer
{
int npackets;
UDPpacket** packetV;
int m_howmany;
UDPpacket** m_packetV;
public:
UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_t size);
~UDPpacketVBuffer (void)
{
if (packetV)
if (m_packetV)
{
SDLNet_FreePacketV (packetV);
packetV = NULL;
SDLNet_FreePacketV (m_packetV);
m_packetV = NULL;
}
}
int Send (UDPsocket sock)
{
int numsent = 0;
if (packetV)
if ((NULL != m_packetV) && (m_howmany > 0))
{
numsent = SDLNet_UDP_SendV (sock, packetV, npackets);
numsent = SDLNet_UDP_SendV (sock, m_packetV, m_howmany);
}
return numsent;
}
std::string Reassemble (void);
};

11
include/lib_GetOpt.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
struct Init_CommonOpts
{
const char* host;
int channel;
int mtu;
unsigned short port;
};
void common_GetOpt (int, char**, Init_CommonOpts*);

View File

@ -26,15 +26,16 @@ bool command_Echo (const std::string& args)
bool command_Shell (const std::string& args)
{
int rc;
if (args.empty ())
char output[8192];
FILE *fp;
if (!args.empty ())
{
}
else
{
c = system (args.c_str ());
switch (rc)
if ((fp = popen (args.c_str (), "r")))
{
while (fgets (output, (sizeof output) - 1, fp) != NULL) {
printf ("%s", output);
}
pclose (fp);
}
}

76
src/SafeUDPpacket.cpp Normal file
View File

@ -0,0 +1,76 @@
#include "SafeUDPpacket.h"
SafeUDPpacketV::SafeUDPpacketV (const void* buf, const int size, const int mtu)
{
int howmany, i, len, numsent;
const uint8_t* bufPtr;
const uint8_t* bufPtrEnd;
SDL_assert (NULL != buf);
SDL_assert (mtu > 0);
howmany = (int) ceil ((double) size / (double) mtu);
i = 0;
numsent = 0;
bufPtr = (const uint8_t*) buf;
bufPtrEnd = bufPtr + size;
while ((i < howmany) && (bufPtr < bufPtrEnd) && (numsent < size))
{
SafeUDPpacket p (mtu);
len = size - numsent;
if (len > mtu)
len = mtu;
/* Use SDLNet_UDP_Send to send an empty packet instead... it's probably simpler than all this machinery. */
if (len < 1)
break;
SDL_memset (p.data (), 0, mtu);
p.len (len);
p.maxlen (size);
/* But only memcpy in the relevant bits */
SDL_memcpy (p.data (), bufPtr, len);
m_packetV.push_back (std::move (p));
/* But we will want the destination address of this packet */
/* Advance */
bufPtr += len;
numsent += len;
i++;
}
SDL_assert (howmany == (int)m_packetV.size ());
}
std::string
SafeUDPpacketV::toString (void)
{
int howmany, maxlen, mtu, numrecv;
char* bufPtr;
char* bufPtrEnd;
std::string buf;
howmany = m_packetV.size ();
SDL_assert (howmany > 0);
maxlen = m_packetV[0].maxlen ();
SDL_assert (maxlen > 0);
buf.reserve (maxlen);
bufPtr = &buf[0];
bufPtrEnd = bufPtr + maxlen;
for (numrecv = 0; (numrecv < howmany) && (bufPtr < bufPtrEnd); numrecv++)
{
mtu = m_packetV[numrecv].len ();
SDL_assert (mtu > 0);
memcpy (bufPtr, m_packetV[numrecv].data (), mtu);
bufPtr += mtu;
}
SDL_assert (numrecv == howmany);
return buf;
}

View File

@ -55,12 +55,17 @@ Server::AllocateApproximateResources (const int nclients)
/*
* If each client sends 1024 250 byte packets, that's 1/4th of a MB or 256000 bytes ...
* seems fine for now as an upper limit.
*
* Since writing that comment, DEFAULT_MAX_PACKET_RECV_SIZE seems to have become 1024.
* So, if 1024 clients are sending 1024 byte packets, we'll need 1 MB of memory.
*
* If 512 clients sending 512 byte packets, that's still 256000 bytes.
*/
if (packetV)
{
SDLNet_FreePacketV (packetV);
}
if (!(packetV = SDLNet_AllocPacketV (1024 * nclients, DEFAULT_MAX_PACKET_RECV_SIZE)))
if (!(packetV = SDLNet_AllocPacketV (2 * nclients, DEFAULT_MAX_PACKET_RECV_SIZE)))
{
SDL_Log ("SDLNet_AllocPacketV: %s", SDLNet_GetError ());
return -1;
@ -215,6 +220,12 @@ Uint32 Server::FetchPacketsCallback (Uint32 interval, void *param)
* TODO fix this wait timeout blocking issue
*
* I want this to block, but also to be stoppable.
*
* Maybe I can have clients send a disconnect packet, then when the queue is zero, stop this thread?
*
* How would clients send a connect packet? I'd have to listen indefinitely and that would block.
*
* Tricky tricky!
*/
numready = SDLNet_CheckSockets (server->getSocketSet (), (1000 * DEFAULT_SOCKET_TIMEOUT / 3) / 1000);
if (numready < 0)

View File

@ -13,10 +13,10 @@ UDPpacketVBuffer::UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_
mtu = src->len;
SDL_assert (mtu > 0);
npackets = (int) ceil ((double) size / (double) mtu);
// SDL_Log ("%d", npackets);
m_howmany = (int) ceil ((double) size / (double) mtu);
// SDL_Log ("%d", m_howmany);
if (NULL == (packetV = SDLNet_AllocPacketV (npackets, mtu)))
if (NULL == (m_packetV = SDLNet_AllocPacketV (m_howmany, mtu)))
{
throw "SDLNet_AllocPacketV: " + std::string (SDLNet_GetError ());
}
@ -25,7 +25,7 @@ UDPpacketVBuffer::UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_
nsent = size;
bufPtr = (const uint8_t*) buf;
bufPtrEnd = bufPtr + size;
while ((i < npackets) && (bufPtr < bufPtrEnd) && (nsent > 0))
while ((i < m_howmany) && (bufPtr < bufPtrEnd) && (nsent > 0))
{
len = nsent;
if (len > mtu)
@ -37,20 +37,51 @@ UDPpacketVBuffer::UDPpacketVBuffer (UDPpacket* src, const void* buf, const size_
/* SDLNet_UDP_Send sets the channel in the argument,
* this one takes it implicitly from the source UDPpacket.
* Set it for all packets in the vector. */
packetV[i]->channel = src->channel;
m_packetV[i]->channel = src->channel;
/* Always zero out the entire data */
SDL_memset (packetV[i]->data, 0, mtu);
SDL_memset (m_packetV[i]->data, 0, mtu);
/* But only memcpy in the relevant bits */
SDL_memcpy (packetV[i]->data, bufPtr, len);
packetV[i]->len = len;
SDL_memcpy (m_packetV[i]->data, bufPtr, len);
m_packetV[i]->len = len;
/* probably don't need maxlen or status set after this */
packetV[i]->maxlen = size;
packetV[i]->status = 0;
m_packetV[i]->maxlen = size;
m_packetV[i]->status = 0;
/* But we will want the destination address of this packet */
packetV[i]->address = src->address;
m_packetV[i]->address = src->address;
/* Advance */
bufPtr += len;
nsent -= len;
i++;
}
}
std::string
UDPpacketVBuffer::Reassemble (void)
{
int i, maxlen, mtu, numrecv;
char* bufPtr;
char* bufPtrEnd;
std::string buf;
SDL_assert (NULL != m_packetV);
SDL_assert (NULL != m_packetV[0]);
maxlen = m_packetV[0]->maxlen;
SDL_assert (maxlen > 0);
buf.reserve (maxlen);
bufPtr = &buf[0];
bufPtrEnd = bufPtr + maxlen;
for (numrecv = 0; (numrecv < m_howmany) && m_packetV[numrecv] && (bufPtr < bufPtrEnd); numrecv++)
{
mtu = m_packetV[numrecv]->len;
SDL_assert (mtu > 0);
memcpy (bufPtr, m_packetV[numrecv]->data, mtu);
bufPtr += mtu;
}
SDL_assert (numrecv == m_howmany);
return buf;
}

View File

@ -11,6 +11,7 @@
#include "UDPbase.h"
#include "UDPpacketVBuffer.h"
#include "events_common.h"
#include "lib_GetOpt.h"
#include <memory>
#include <vector>
@ -33,11 +34,9 @@ static bool my_Input (SDL_Event*);
static bool my_SDL_UserEvent (SDL_Event*);
static bool my_SDL_WindowEvent (SDL_Event*);
static void my_GetOpt (int, char**);
static void my_Init (int, char**);
static void my_Render (void);
static void my_UpdateValues (void);
static void my_Usage (const char*);
struct Uniform_Values
{
@ -56,16 +55,19 @@ struct Uniform_Values
struct Client_State
{
Init_CommonOpts init_opts;
const char* host;
int channel;
int mtu;
Uint16 port;
bool done;
Uint64 start, end;
double diff;
UDPsocket udpsock;
const char* host;
Uint16 port;
int channel;
int mtu;
SDL_GLContext GLContext;
SDL_Window* Window;
@ -86,7 +88,6 @@ struct Client_State
static std::unique_ptr<Cube> cube;
static std::unique_ptr<Quad> quad;
static std::unique_ptr<ShaderProgram> shader;
static std::unique_ptr<UDPbase> client;
static Camera camera;
static struct Client_State state;
@ -95,87 +96,94 @@ static struct Uniform_Values values;
int
main (int argc, char** argv)
{
glm::mat4 model, view, projection;
SDL_Event event;
my_Init (argc, argv);
shader = std::make_unique<ShaderProgram> ("./glsl/camera.v.glsl", "", "./glsl/new.f.glsl");
if (!shader->ID)
{
SDL_Log ("Unable to load shader.");
goto _out;
}
glm::mat4 model, view, projection;
SDL_Event event;
std::unique_ptr<UDPbase> client;
camera = Camera ();
values.iResolution.x = state.Window_Width;
values.iResolution.y = state.Window_Height;
values.iResolution.z = 1.0;
my_Init (argc, argv);
cube = std::make_unique<Cube> (1);
quad = std::make_unique<Quad> (1);
state.mtu = 1450;
state.done = false;
client = std::make_unique<UDPbase> (state.host, state.port, state.channel);
if (NULL == (state.udpsock = client->getSocket (0)))
{
SDL_Log ("Unable to open client port");
goto _out;
}
if (-1 == (state.channel = client->getChannel ()))
{
SDL_Log ("Unable to bind client port");
goto _out;
}
while (!state.done)
{
state.end = SDL_GetPerformanceCounter ();
state.diff = Perf_Diff (state.start, state.end);
while (state.diff < MIN_FRAME_MS)
shader = std::make_unique<ShaderProgram> ("./glsl/camera.v.glsl", "", "./glsl/new.f.glsl");
if (!shader->ID)
{
SDL_Log ("Unable to load shader.");
goto _out;
}
camera = Camera ();
values.iResolution.x = state.Window_Width;
values.iResolution.y = state.Window_Height;
values.iResolution.z = 1.0;
cube = std::make_unique<Cube> (1);
quad = std::make_unique<Quad> (1);
state.done = false;
/* XXX is this okay? We are using C++ after all.. inheritance time */
state.mtu = state.init_opts.mtu;
state.host = state.init_opts.host;
state.channel = state.init_opts.channel;
state.port = state.init_opts.port;
client = std::make_unique<UDPbase> (state.host, state.port, state.channel);
if (NULL == (state.udpsock = client->getSocket (0)))
{
SDL_Log ("Unable to open client port");
goto _out;
}
if (-1 == (state.channel = client->getChannel ()))
{
SDL_Log ("Unable to bind client port");
goto _out;
}
while (!state.done)
{
SDL_Delay (1);
state.end = SDL_GetPerformanceCounter ();
state.diff = Perf_Diff (state.start, state.end);
while (state.diff < MIN_FRAME_MS)
{
SDL_Delay (1);
state.end = SDL_GetPerformanceCounter ();
state.diff = Perf_Diff (state.start, state.end);
}
state.start = SDL_GetPerformanceCounter ();
SDL_SetRelativeMouseMode ((SDL_bool) state.InputRelativeMouseMode);
SDL_CaptureMouse ((SDL_bool) state.InputCaptureMouse);
while (!state.done && SDL_PollEvent (&event))
{
state.done = my_Input (&event);
}
my_AnalogInput ();
projection = glm::perspective (glm::radians (camera.Zoom), (float) values.iResolution.x / (float) values.iResolution.y, camera.zNear, camera.zFar);
view = camera.GetViewMatrix ();
model = glm::mat4 (1.0f);
my_UpdateValues ();
shader->Use ();
shader->Mat4 ("Projection", projection);
shader->Mat4 ("View", view);
shader->Mat4 ("Model", model);
my_Render ();
model = glm::mat4 (1.0f);
model = glm::scale (model, glm::vec3 (10.0f));
shader->Use ();
shader->Mat4 ("Projection", projection);
shader->Mat4 ("View", view);
shader->Mat4 ("Model", model);
cube->Draw ();
SDL_GL_SwapWindow (state.Window);
}
state.start = SDL_GetPerformanceCounter ();
SDL_SetRelativeMouseMode ((SDL_bool) state.InputRelativeMouseMode);
SDL_CaptureMouse ((SDL_bool) state.InputCaptureMouse);
while (!state.done && SDL_PollEvent (&event))
{
state.done = my_Input (&event);
}
my_AnalogInput ();
projection = glm::perspective (glm::radians (camera.Zoom), (float) values.iResolution.x / (float) values.iResolution.y, camera.zNear, camera.zFar);
view = camera.GetViewMatrix ();
model = glm::mat4 (1.0f);
my_UpdateValues ();
shader->Use ();
shader->Mat4 ("Projection", projection);
shader->Mat4 ("View", view);
shader->Mat4 ("Model", model);
my_Render ();
model = glm::mat4 (1.0f);
model = glm::scale (model, glm::vec3 (10.0f));
shader->Use ();
shader->Mat4 ("Projection", projection);
shader->Mat4 ("View", view);
shader->Mat4 ("Model", model);
cube->Draw ();
SDL_GL_SwapWindow (state.Window);
}
_out:
client->CloseAllSockets ();
SDL_GL_DeleteContext (state.GLContext);
SDL_DestroyWindow (state.Window);
common_SDL_Quit ();
@ -188,7 +196,8 @@ static void
my_Init (int argc, char** argv)
{
common_Signal_Init ();
my_GetOpt (argc, argv);
common_GetOpt (argc, argv, &state.init_opts);
state.start = state.end = SDL_GetPerformanceCounter ();
@ -314,7 +323,7 @@ my_Input (SDL_Event* event)
case SHADER_PROGRAM_REFRESH:
my_SDL_UserEvent (event);
break;
break;
break;
case SDL_WINDOWEVENT:
my_SDL_WindowEvent (event);
break;
@ -467,7 +476,8 @@ my_SDL_UserEvent (SDL_Event* event)
SDL_Log ("SHADER_PROGRAM_REFRESH");
/* Actually do the refresh */
GLuint id;
try {
try
{
id = shader->Compile3ShaderBuffers (shader->getVertexPath (), shader->getGeometryPath (), shader->getFragmentPath ());
}
catch (const std::string& e)
@ -510,37 +520,3 @@ my_SDL_WindowEvent (SDL_Event* event)
}
return done;
}
static void
my_Usage (const char* argv0)
{
fprintf (stderr, "Usage: %s [-h] [-s host] [-p port]\n", argv0);
}
static void
my_GetOpt (int argc, char** argv)
{
int opt;
state.host = "localhost";
state.port = 6666;
state.channel = -1;
while ((opt = getopt (argc, argv, "hp:s:")) != -1)
{
switch (opt)
{
case 'p':
state.port = strtol (optarg, NULL, 0);
break;
case 's':
state.host = optarg;
break;
case 'h':
default:
my_Usage (argv[0]);
exit (EXIT_FAILURE);
break;
}
}
}

43
src/lib_GetOpt.cpp Normal file
View File

@ -0,0 +1,43 @@
#include "lib_GetOpt.h"
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void
common_Usage (const char* argv0)
{
fprintf (stderr, "Usage: %s [-h] [-s server] [-p port]\n", argv0);
}
void
common_GetOpt (int argc, char** argv, Init_CommonOpts* state)
{
int opt;
state->host = "localhost";
state->channel = -1;
state->mtu = 1450;
state->port = 6666;
while ((opt = getopt (argc, argv, "hm:p:s:")) != -1)
{
switch (opt)
{
case 'm':
state->mtu = strtol (optarg, NULL, 0);
break;
case 'p':
state->port = strtol (optarg, NULL, 0);
break;
case 's':
state->host = optarg;
break;
case 'h':
default:
common_Usage (argv[0]);
exit (EXIT_FAILURE);
break;
}
}
}

View File

@ -8,6 +8,7 @@
#include "util.h"
#include "Server.h"
#include "Commands.h"
#include "lib_GetOpt.h"
#include <iostream>
#include <fstream>
@ -21,16 +22,16 @@
#include <getopt.h> /* getopt */
static bool done = false;
static const char* host = NULL;
static Uint16 port = 6666;
static const char* prompt_str = "> ";
/* XXX gross */
static std::vector<char> server_data;
static bool left_shift = false;
static std::unique_ptr<Server> server;
static bool my_SDL_UserEvent (SDL_Event *);
static int my_StdinThread(void*);
static void my_Usage (const char *);
static void my_GetOpt (int, char **);
static void my_ProcessPacket (UDPpacket *);
static bool my_StdinThread_Helper (const std::string&);
static void my_ShowPrompt (void);
@ -38,13 +39,14 @@ static void my_ShowPrompt (void);
int
main (int argc, char **argv)
{
Init_CommonOpts init_opts;
SDL_Event ev;
my_GetOpt (argc, argv);
common_GetOpt (argc, argv, &init_opts);
common_Signal_Init ();
common_SDL_Init ();
server = std::make_unique<Server> (host, port);
server = std::make_unique<Server> (init_opts.host, init_opts.port);
if (server->Start () < 0)
{
@ -116,10 +118,6 @@ my_SDL_UserEvent (SDL_Event * ev)
/* XXX gross */
static std::vector<char> server_data;
static bool left_shift = false;
/* XXX gross */
static void
my_ProcessPacket (UDPpacket* packet)
{
@ -237,37 +235,6 @@ my_ProcessPacket (UDPpacket* packet)
}
static void
my_Usage (const char *argv0)
{
fprintf (stderr, "Usage: %s [-h] [-s server] [-p port]\n", argv0);
}
static void
my_GetOpt (int argc, char **argv)
{
int opt;
while ((opt = getopt (argc, argv, "hp:s:")) != -1)
{
switch (opt)
{
case 'p':
port = strtol (optarg, NULL, 0);
break;
case 's':
host = optarg;
break;
case 'h':
default:
my_Usage (argv[0]);
exit (EXIT_FAILURE);
break;
}
}
}
static void my_ShowPrompt (void)
{
printf ("\n%s", prompt_str);

View File

@ -0,0 +1,11 @@
#include "SafeUDPpacket.h"
int main(void)
{
int size;
size = 1;
UDPpacket* p_ptr;
SafeUDPpacket p (size);
p_ptr = p.get ();
return 0;
}

View File

@ -40,54 +40,54 @@ static std::unique_ptr<UDPbase> client;
int
main (int argc, char **argv)
{
UDPsocket udpsock;
common_Signal_Init ();
my_GetOpt (argc, argv);
common_SDL_Init ();
client = std::make_unique<UDPbase> (host, port);
if (NULL == (udpsock = client->UDP_Open (0)))
{
SDL_Log ("Unable to open client port");
return -1;
}
if (-1 == (channel = client->UDP_Bind (udpsock, -1)))
{
SDL_Log ("Unable to bind client port");
return -1;
}
UDPsocket udpsock;
std::string buf;
if (path == "-")
{
try {
std::string line;
while (getline (std::cin, line))
{
buf += line + "\n";
common_Signal_Init ();
my_GetOpt (argc, argv);
common_SDL_Init ();
client = std::make_unique<UDPbase> (host, port);
if (NULL == (udpsock = client->UDP_Open (0)))
{
SDL_Log ("Unable to open client port");
return -1;
}
if (-1 == (channel = client->UDP_Bind (udpsock, -1)))
{
SDL_Log ("Unable to bind client port");
return -1;
}
std::string buf;
if (path == "-")
{
try {
std::string line;
while (getline (std::cin, line))
{
buf += line + "\n";
}
}
catch (std::ifstream::failure& e) {
// std::cout << e << std::endl;
}
}
catch (std::ifstream::failure& e) {
// std::cout << e << std::endl;
else
{
FileIO f (path, "r");
buf = f.ReadToString ();
}
}
else
{
FileIO f (path, "r");
buf = f.ReadToString ();
}
UDPpacket* packet = SDLNet_AllocPacket (buf.length ());
IPaddress* addr = SDLNet_UDP_GetPeerAddress (udpsock, channel);
packet->len = DEFAULT_MAX_PACKET_SIZE;
packet->address = *addr;
packet->channel = channel;
UDPpacketVBuffer packetV (packet, &buf[0], buf.length ());
packetV.Send (udpsock);
client->CloseAllSockets ();
UDPpacket* packet = SDLNet_AllocPacket (buf.length ());
IPaddress* addr = SDLNet_UDP_GetPeerAddress (udpsock, channel);
packet->len = DEFAULT_MAX_PACKET_SIZE;
packet->address = *addr;
packet->channel = channel;
UDPpacketVBuffer packetV (packet, &buf[0], buf.length ());
packetV.Send (udpsock);
}
common_SDL_Quit ();