New API: Comments?

  1. You’re still not object-oriented. You therefore still can’t use this
    api more
    than once in a single process. Please consider defining a type
    sdlnet_t
    and making all the calls that currently need static data store it in
    the sdlnet_t instead, and take a pointer to an sdlnet_t!

IMHO, the function that picks the UDP port number ought to be
called something like sdlnet_udp_init(sdlnet_t *, short port), to indicate
you do it only once per session.

I’m very confused about what a channel is and what a socket is.
In my API, the send and receive routines operate on handles,
which are integers in the range 0…nhandles.

Your channel seems to be a subaddress on a socket? I think that rather
than having calls that take a subchannel like that,

  1. Types need to start with the standard prefix, too. All identifiers that
    get
    declared in your .h file must be protected in this way from clashes.
    e.g. sdlnet_ipadr_t rather than IPAddress.

My taste also runs towards the left-to-right more-generic-to-less-generic,
e.g. sdlnet_udp_sendv().

  1. sendudp should not do a soft broadcast; let the higher level do that.
    It should do a hardware broadcast. This is partly because hardware
    broadcasts are needed on LAN’s to advertize games, and partly
    because the upper layer usually has handles open to extra hosts
    not involved in the game per se (e.g. an auxillary server, or a lurker).
    Well, at least my upper layer does :slight_smile:

  2. The packet buffer should have a status field so that each packet
    processed by send or receive can have a separate result code, IMHO.
    Your doc should mention that the API is designed to reuse existing
    packet buffers rather than constantly allocate new ones, to avoid
    heap fragmentation.

  3. getpeername probably needs to return all bound addresses for that peer.
    Likewise, setpeername should set all bound addresses.
    One address, the first one in the vector, should by convention be
    the primary address - the one visible to the outside world. Addresses
    should be six bytes long, because the port number is variable under NAT.

Uh, I’m not sure about passing a channel number to the bind function.
I’d rather call that sdlnet_udp_open(), and pass it a vector of addresses.
Most users will pass only one address.

  1. Tactically speaking, it is a very good idea to have a separate .h file
    for the shared error code type and #define’s for a family of modules,
    e.g. sdlerr.h. That way, you can pull in the error codes into lowlevel
    modules
    like sdlnet without pulling in higher-level baggage.> -----Original Message-----

From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Thursday, October 29, 1998 12:12 PM
To: @Kegel_Dan
Subject: New API: Comments?

Note that I omitted getpeername() on purpose.
I’m still working out the best implementation.

/*
NETLIB: An example cross-platform network library for use with SDL
Copyright © 1997 Sam Lantinga

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307

USA

Sam Lantinga
5635-34 Springhouse Dr.
Pleasanton, CA 94588 (USA)
slouken at devolution.com

*/

#ifndef _SDLnet_h
#define _SDLnet_h

#include “SDL.h”

/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern “C” {
#endif

/* Initialize/Cleanup the network API
SDL must be initialized before calls to functions in this library,
because this library uses utility functions from the SDL library.
*/
extern int Net_Init(void);
extern void Net_Quit(void);

//
/* TCP network API */
/
/

typedef struct TCPsocket *TCPsocket;

/* Open a TCP network socket
If ‘remote’ is NULL, this creates a local server socket on the given
port,
otherwise a TCP connection to the remote host and port is attempted.
The newly created socket is returned, or NULL if there was an error.
*/
extern TCPsocket SDLNet_OpenTCP(char *remote, Uint16 port);

/* Accept an incoming connection on the given server socket.
The newly created socket is returned, or NULL if there was an error.
*/
extern TCPsocket SDLNet_AcceptTCP(TCPsocket server);

/* Send ‘len’ bytes of ‘data’ over the non-server socket 'sock’
This function returns the actual amount of data sent. If the return
value
is less than the amount of data sent, then either the remote connection
was
closed, or an unknown socket error occurred.
*/
extern int SDLNet_SendTCP(TCPsocket sock, char *data, int len);

/* Returns true if the socket is ready to recieve data, blocking for up to
’timeout’ milliseconds before returning.
If a server socket is passed to this function, then it will return true
when there is an incoming connection to be accepted.
*/
extern int SDLNet_ReadyTCP(UDPsocket sock, Uint32 timeout);

/* Receive up to ‘maxlen’ bytes of data over the non-server socket ‘sock’,
and store them in the buffer pointed to by ‘data’.
This function returns the actual amount of data received. If the
return
value is less than or equal to zero, then either the remote connection
was
closed, or an unknown socket error occurred.
*/
extern int SDLNet_RecvTCP(TCPsocket sock, char *data, int maxlen);

/* Close a TCP network socket */
extern void SDLNet_CloseTCP(TCPsocket sock);

//
/* UDP network API */
/
/

/* The maximum channels on a a UDP socket (should be a multiple of 8) /
#define SDLNET_MAX_UDPCHANNELS 32
/
The maximum addresses bound to a single UDP socket channel */
#define SDLNET_MAX_UDPADDRESSES 4

typedef struct UDPsocket *UDPsocket;
typedef struct {
char data; / The packet data /
int len; /
The length of the packet data /
int maxlen; /
The size of the data buffer /
IPaddress src; /
The source address of the packet /
int channel; /
The source channel of the packet */
} UDPpacket;

/* Open a UDP network socket
If ‘port’ is non-zero, the UDP socket is bound to a local port.
This allows other systems to send to this socket
*/
extern UDPsocket SDLNet_OpenUDP(Uint16 port);

/* Bind the address ‘address’ to the requested channel on the UDP socket.
If the channel is already bound, this new address will be added to the
valid addresses for the channel.
If the channel is -1, then the first unbound channel will be bound with
the given address.
This function returns the channel which was bound, or -1 on error.
*/
extern int SDLNet_BindUDP(UDPsocket sock, int channel, IPaddress address);

/* Allocate/free a single UDP packet ‘size’ bytes long.
The new packet is returned, or NULL if the function ran out of memory.
*/
extern UDPpacket *SDLNet_AllocPacket(int size);
extern void SDLNet_FreePacket(UDPpacket *packet);

/* Allocate/Free a UDP packet vector (array of packets) of 'howmany’
packets,
each ‘size’ bytes long.
A pointer to the first packet in the array is returned, or NULL if the
function ran out of memory.
*/
extern UDPpacket **SDLNet_AllocPacketV(int howmany, int size);
extern void SDLNet_FreePacketV(UDPpacket **packetV);

/* Send a vector of packets to the addresses bound to the given channel.
If ‘channel’ is -1, the packets are broadcast to every address on every
channel bound on the UDP socket.
This function returns the number of packets sent, or -1 on error.
*/
extern int SDLNet_SendVUDP(UDPsocket sock, int channel, int howmany,
UDPpacket **packetV);
#define SDLNet_SendUDP(s, c, p) SDLNet_SendVUDP(s, c, 1, &p)

/* Returns true if the socket is ready to recieve data, blocking for up to
’timeout’ milliseconds before returning.
*/
extern int SDLNet_ReadyUDP(UDPsocket sock, Uint32 timeout);

/* Receive a vector of pending packets from the UDP socket.
The returned packets contain the source address and the channel they
arrived
on. If they did not arrive on a bound channel, the the channel will be
set
to -1.
This function returns the number of packets read from the network, or
-1
on error.
This function does not block, so can return 0 packets pending.
*/
extern int SDLNet_RecvVUDP(UDPsocket sock, int howmany, UDPpacket
**packetV);
#define SDLNet_RecvUDP(s, p) SDLNet_SendVUDP(s, 1, &p)

/* Close a UDP network socket */
extern void SDLNet_CloseUDP(UDPsocket sock);

//
/* Platform-independent data conversion functions */
/
/

/* Write a 16/32 bit value to network packet buffer */
extern void Net_Write16(Uint16 value, Uint8 *area);
extern void Net_Write32(Uint32 value, Uint8 *area);

/* Read a 16/32 bit value from network packet buffer */
extern Uint16 Net_Read16(Uint8 *area);
extern Uint32 Net_Read32(Uint8 *area);

//
/* Error reporting functions */
/
/

/* We’ll use SDL’s functions for error reporting */
#define Net_SetError SDL_SetError
#define Net_GetError SDL_GetError

/* Ends C function definitions when using C++ /
#ifdef __cplusplus
};
#endif
#endif /
_SDLnet_h */

Last comments today. I gotta work, y’know!

I am object oriented. The object is the TCPsocket or UDPsocket.
Ignore SDLNet_Init(), and SDLNet_Quit() – they are just used to initialize
the Win32 socket layer. A simple reference count in there will take care
of
multiple calls.
I am not using C++.
I see now that you’re doing what I was talking about. I was thrown off a
bit
by SDLNet_UDPsocket. I still feel a little queasy. Fear not, it should
pass.

extern int SDLNet_SendVUDP(UDPsocket sock, int channel, int howmany,
UDPpacket **packetV);
Aha. You need to accept a vector of channel numbers here, too, to support
groups and broadcast. So perhaps
sdlnet_udp_send(sdlnet_udp_t *sock, int *channels, int nchannels,
sdlnet_packet_t *packetV, int npackets);

:slight_smile: What are hardware broadcasts? 192.168.0.255?
Can you specify a port on a hardware broadcast?
Hardware broadcasts are when you send to address 255.255.255.255.
By the way, you might want to preopen a handle to that address.

Good question about the port. The only time you need hardware
broadcast is when running on a LAN. In that case, everyone has to
use the same port number. The hardware broadcast is sent and
received with the same port number.
When running on the Internet, the port number may vary for
several reasons, but one doesn’t need hardware broadcast on the Internet.

  1. The packet buffer should have a status field so that each packet
    processed by send or receive can have a separate result code, IMHO.
    Did you catch this one ?-)

udp_socket = opensocket
for host in clients
do # bind the host address to the next free channel
sdlnet_udp_bind(udp_socket, -1, host, port)
done

Small note: can’t assume you know all the IP adrs of the peers at this
point. You’re more likely to do the binding when you receive a
"please let me join" packet from an unbound source. Maybe sdlnet_udp_bind
should take an IPAddress instead of separate host and port?

       # Receive status updates
       while numupdated < numclients
  do sdlnet_udp_recv(udp_socket, packets)
          for packet in packets
          do update(packet->channel, packet);
             ++numupdated
          done

But what about dropped packets? In action sim land, one accepts that and
moves
on. (Strategy games in lockstep require a higher level protocol to make
things
reliable.) So a slightly better example is to just process all outstanding
packets
and move on. You still need an outer loop, in case your packet vector
isn’t big enough.
# Receive status updates until no more available
while sdlnet_udp_recv(udp_socket, packets, maxpackets) ==
maxpackets
do
for packet in packets
do

There is, SDL_error.h
It’s just included in SDL.h
Am I misunderstanding you?
Yeah. You may find it painful to include SDL.h from within
submodules of SDL. Each .h file is protected against
multiple inclusion, but there are occasionally painful side
effects of including toplevel .h files in submodules.
It’s kind of like how your head hurts when you run into
those twisty passages all alike in Adventure :slight_smile:
You’ll understand if/when you run into it, but for now,
I’m just suggesting that it’s good to include the weakest
.h files you possibly can inside submodule .h files.> > > -----Original Message-----

From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Thursday, October 29, 1998 12:12 PM
To: @Kegel_Dan
Subject: New API: Comments?

Note that I omitted getpeername() on purpose.
I’m still working out the best implementation.

/*
NETLIB: An example cross-platform network library for use with
SDL

Copyright (C) 1997  Sam Lantinga

This program is free software; you can redistribute it and/or

modify

it under the terms of the GNU General Public License as published

by

the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA

02111-1307

USA

Sam Lantinga
5635-34 Springhouse Dr.
Pleasanton, CA 94588 (USA)
slouken at devolution.com

*/

#ifndef _SDLnet_h
#define _SDLnet_h

#include “SDL.h”

/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern “C” {
#endif

/* Initialize/Cleanup the network API
SDL must be initialized before calls to functions in this library,
because this library uses utility functions from the SDL library.
*/
extern int Net_Init(void);
extern void Net_Quit(void);

/***********************************************************************/

/* TCP network API
*/

/***********************************************************************/

typedef struct TCPsocket *TCPsocket;

/* Open a TCP network socket
If ‘remote’ is NULL, this creates a local server socket on the
given

port,
otherwise a TCP connection to the remote host and port is
attempted.

The newly created socket is returned, or NULL if there was an
error.

*/
extern TCPsocket SDLNet_OpenTCP(char *remote, Uint16 port);

/* Accept an incoming connection on the given server socket.
The newly created socket is returned, or NULL if there was an
error.

*/
extern TCPsocket SDLNet_AcceptTCP(TCPsocket server);

/* Send ‘len’ bytes of ‘data’ over the non-server socket 'sock’
This function returns the actual amount of data sent. If the
return

value
is less than the amount of data sent, then either the remote
connection

was
closed, or an unknown socket error occurred.
*/
extern int SDLNet_SendTCP(TCPsocket sock, char *data, int len);

/* Returns true if the socket is ready to recieve data, blocking for
up to

‘timeout’ milliseconds before returning.
If a server socket is passed to this function, then it will return
true

when there is an incoming connection to be accepted.
*/
extern int SDLNet_ReadyTCP(UDPsocket sock, Uint32 timeout);

/* Receive up to ‘maxlen’ bytes of data over the non-server socket
’sock’,

and store them in the buffer pointed to by ‘data’.
This function returns the actual amount of data received. If the
return
value is less than or equal to zero, then either the remote
connection

was
closed, or an unknown socket error occurred.
*/
extern int SDLNet_RecvTCP(TCPsocket sock, char *data, int maxlen);

/* Close a TCP network socket */
extern void SDLNet_CloseTCP(TCPsocket sock);

/***********************************************************************/

/* UDP network API
*/

/***********************************************************************/

/* The maximum channels on a a UDP socket (should be a multiple of 8)
*/

#define SDLNET_MAX_UDPCHANNELS 32
/* The maximum addresses bound to a single UDP socket channel */
#define SDLNET_MAX_UDPADDRESSES 4

typedef struct UDPsocket *UDPsocket;
typedef struct {
char data; / The packet data /
int len; /
The length of the packet data /
int maxlen; /
The size of the data buffer /
IPaddress src; /
The source address of the packet /
int channel; /
The source channel of the packet */
} UDPpacket;

/* Open a UDP network socket
If ‘port’ is non-zero, the UDP socket is bound to a local port.
This allows other systems to send to this socket
*/
extern UDPsocket SDLNet_OpenUDP(Uint16 port);

/* Bind the address ‘address’ to the requested channel on the UDP
socket.

If the channel is already bound, this new address will be added to
the

valid addresses for the channel.
If the channel is -1, then the first unbound channel will be bound
with

the given address.
This function returns the channel which was bound, or -1 on error.
*/
extern int SDLNet_BindUDP(UDPsocket sock, int channel, IPaddress
address);

/* Allocate/free a single UDP packet ‘size’ bytes long.
The new packet is returned, or NULL if the function ran out of
memory.

*/
extern UDPpacket *SDLNet_AllocPacket(int size);
extern void SDLNet_FreePacket(UDPpacket *packet);

/* Allocate/Free a UDP packet vector (array of packets) of 'howmany’
packets,
each ‘size’ bytes long.
A pointer to the first packet in the array is returned, or NULL if
the

function ran out of memory.
*/
extern UDPpacket **SDLNet_AllocPacketV(int howmany, int size);
extern void SDLNet_FreePacketV(UDPpacket **packetV);

/* Send a vector of packets to the addresses bound to the given
channel.

If ‘channel’ is -1, the packets are broadcast to every address on
every

channel bound on the UDP socket.
This function returns the number of packets sent, or -1 on error.
*/
extern int SDLNet_SendVUDP(UDPsocket sock, int channel, int howmany,
UDPpacket **packetV);
#define SDLNet_SendUDP(s, c, p) SDLNet_SendVUDP(s, c, 1, &p)

/* Returns true if the socket is ready to recieve data, blocking for
up to

‘timeout’ milliseconds before returning.
*/
extern int SDLNet_ReadyUDP(UDPsocket sock, Uint32 timeout);

/* Receive a vector of pending packets from the UDP socket.
The returned packets contain the source address and the channel
they

arrived
on. If they did not arrive on a bound channel, the the channel
will be

set
to -1.
This function returns the number of packets read from the network,
or

-1
on error.
This function does not block, so can return 0 packets pending.
*/
extern int SDLNet_RecvVUDP(UDPsocket sock, int howmany, UDPpacket
**packetV);
#define SDLNet_RecvUDP(s, p) SDLNet_SendVUDP(s, 1, &p)

/* Close a UDP network socket */
extern void SDLNet_CloseUDP(UDPsocket sock);

/***********************************************************************/

/* Platform-independent data conversion functions
*/

/***********************************************************************/

/* Write a 16/32 bit value to network packet buffer */
extern void Net_Write16(Uint16 value, Uint8 *area);
extern void Net_Write32(Uint32 value, Uint8 *area);

/* Read a 16/32 bit value from network packet buffer */
extern Uint16 Net_Read16(Uint8 *area);
extern Uint32 Net_Read32(Uint8 *area);

/***********************************************************************/

/* Error reporting functions
*/

/***********************************************************************/

/* We’ll use SDL’s functions for error reporting */
#define Net_SetError SDL_SetError
#define Net_GetError SDL_GetError

/* Ends C function definitions when using C++ /
#ifdef __cplusplus
};
#endif
#endif /
_SDLnet_h */

See ya!
-Sam Lantinga (slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/

You might exceed the MTU, or overfill a buffer.

ICMP unreachable errors are reported in an interesting way.
I have yet to be able to take advantage of them.

  • Dan> -----Original Message-----

From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Thursday, October 29, 1998 4:40 PM
To: Kegel, Dan
Subject: Re: New API: Comments?

  1. The packet buffer should have a status field so that each packet
    processed by send or receive can have a separate result code, IMHO.
    Did you catch this one ?-)

When does a UDP send or recieve fail? Why would some packets fail and
others
not? ICMP network unreachable type things?

See ya!
-Sam Lantinga (slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/

Hey, I missed you on Friday… we whipped in and out quick-like.
I guess they had plans for lunch. :slight_smile:
Yeah, darn.

Yep. Hey, what do you do for status on a packet that gets sent to multiple
channels? Surely you don’t have a two dimensional array, packet x channel?
I now doubt that the ‘send same packet to multiple destinations’ feature is
good,
because a tidy network game will send packets out very carefully
to individual destinations as the bandwidth model permits.
I retract the suggestion :slight_smile:

I also think your select function misses the boat - you need to provide
a way to select for activity on multiple udp sockets, don’t think yours
does at the moment, does it?

  • Dan

grin So you think “send one packet to one destination” is a good model?
Nah, send a vector of packets to individual destinations is still a good
improvement over that.

I’ll still add a multi-cast feature "send one packet to all destinations"
because it will probably be really useful, and is easy to implement.
OK, but IMHO you’re at the wrong level for it, and it won’t get used
the way you expect. For instance, I have a handle open to the
game server, but I really don’t want to send position packets there.
Doing so causes unneeded traffic and therefore extra lag.

I’m still unsure if I should add the hardware broadcast to a newly opened
socket. How often is it actually used?
It gets used for all game advertizements when doing local lan stuff.

How can you guarantee that all clients/peers are on the local lan?
Games have two modes: one where they connect to a server to find opponants,
one where the LAN acts as the server.

It seems like it could be easily misunderstood by people who don’t
know networking that well, and easily implemented by those who do.
Uh, that goes for your whole library :slight_smile:
How about having two predefined handles: hardware broadcast
and software broadcast, and strongly advising people to use
hardware broadcast only for session advertizements, and not
for in-game data?

  • Dan

Never.> -----Original Message-----

From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Monday, November 02, 1998 12:01 PM
To: Kegel, Dan
Subject: Re: New API: Comments?

I now doubt that the ‘send same packet to multiple destinations’ feature
is
good, because a tidy network game will send packets out very carefully
to individual destinations as the bandwidth model permits.

How often does a tidy network game send multiple packets to a single
destination at once?

See ya!
-Sam Lantinga (slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/

A vector of packets to different destinations.
The vector consists of structures of the form

int channel; /* the source or destination /
int status; /
the result of the send or get operation */
int len;
char *buf;

These structures are used in both send_v and recv_v.

  • Dan> -----Original Message-----

From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Monday, November 02, 1998 12:16 PM
To: Kegel, Dan
Subject: Re: New API: Comments?

If that’s true, then why would you support sending a vector of packets?
Am I misunderstanding what you mean by a vector of packets?

Never.

-----Original Message-----
From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Monday, November 02, 1998 12:01 PM
To: Kegel, Dan
Subject: Re: New API: Comments?

I now doubt that the 'send same packet to multiple destinations’
feature

is

good, because a tidy network game will send packets out very
carefully

to individual destinations as the bandwidth model permits.

How often does a tidy network game send multiple packets to a single
destination at once?

See ya!
-Sam Lantinga (slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/

See ya!
-Sam Lantinga (slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/

You catch on fast, kimosabe.

  • Dan> -----Original Message-----

From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Monday, November 02, 1998 12:50 PM
To: Kegel, Dan
Subject: Re: New API: Comments?

I’m confused. I asked “When does a tidy network game send multiple
packets to a single destination?” and you said “Never”. Isn’t sending
a vector of packets to a destination the same as sending multiple packets
to a destination? Oh… I see. :slight_smile: The trick is you never actually
specify the destination in the function call, you just look at the packet
vector. That way you can do a high level loop to send packets to multiple
destinations, or send multiple packets to the same destination all at
once.

Very cool. :slight_smile:

A vector of packets to different destinations.
The vector consists of structures of the form

int channel; /* the source or destination /
int status; /
the result of the send or get operation */
int len;
char *buf;

These structures are used in both send_v and recv_v.

  • Dan

-----Original Message-----
From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Monday, November 02, 1998 12:16 PM
To: Kegel, Dan
Subject: Re: New API: Comments?

If that’s true, then why would you support sending a vector of
packets?

Am I misunderstanding what you mean by a vector of packets?

Never.

-----Original Message-----
From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Monday, November 02, 1998 12:01 PM
To: Kegel, Dan
Subject: Re: New API: Comments?

I now doubt that the 'send same packet to multiple destinations’
feature

is

good, because a tidy network game will send packets out very
carefully

to individual destinations as the bandwidth model permits.

How often does a tidy network game send multiple packets to a
single

destination at once?

See ya!
-Sam Lantinga
(slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/

See ya!
-Sam Lantinga (slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/

See ya!
-Sam Lantinga (slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/

It be bad to have multiple-statement macros.
if (x)
send;
else
dflka

doesn’t work too well in that case. Better make it a thin function.

  • Dan> -----Original Message-----

From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Monday, November 02, 1998 1:12 PM
To: Kegel, Dan
Subject: Re: New API: Comments?

You catch on fast, kimosabe.

Er, thanks… :-}

I didn’t think about using the channel for the destination in outbound
packets. :slight_smile: I think I’ll make send(c, p) be: p->c = c; send_v(&p, 1)

See ya!
-Sam Lantinga (slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/

http://lwn.net/daily/corel.html

I forgot about winelib, but Corel seems to be a big believer in it.

  • Dan

typedef struct {
int ready;
} *SDLNet_Socket;

mmm. I’m confused about that typedef.
Shouldn’t you have a typedef for sdlnet_socketset?

#define SDLNet_AddSocket(set, n, sock) {
set[n] = (SDLNet_Socket) sock;
}
I’m confused. I thought ready contained a boolean, not a socket number?

extern int SDLNet_CheckSockets(SDLNet_Socket *set, Uint32 timeout);
OK.

#define SDLNet_SocketReady(sock) (((SDLNet_Socket)sock)->ready)
OK.

it’d be nice to have a way to copy a socketset, so you didn’t have to
keep building one from scratch, maybe.

  • Dan

That looks good.> -----Original Message-----

From: Sam Lantinga [SMTP:slouken at devolution.com]
Sent: Monday, November 02, 1998 2:24 PM
To: Kegel, Dan
Subject: Re: New API: Comments?

mmm. I’m confused about that typedef.
Shouldn’t you have a typedef for sdlnet_socketset?

Yeah, probably. I was making SDLNet_AddSocket() into a macro, but
that’s a bit confusing and not necessary for speed. I’ll demonstrate
in the example that follows…

it’d be nice to have a way to copy a socketset, so you didn’t have to
keep building one from scratch, maybe.

You won’t need to:

gameinit(int maxsockets)
{
set = SDLNet_AllocSocketSet(maxsockets);
}

netinit(sock1, sock2) {
SDLNet_TCP_AddSocket(set, sock1);
SDLNet_UDP_AddSocket(set, sock2);
}

while (game_running) {
while ( SDLNet_CheckSockets(set, 0) ) {
if ( SDLNet_SocketReady(sock1) ) {
// Handle control message
}
if ( SDLNet_SocketReady(sock2) ) {
// Handle update packet
}
}
}

cleanup() {
SDLNet_FreeSocketSet(set);
}

Note the changed API… I’ll also need SDLNet_TCP_DelSocket(), but the
point
is that you only need to create the socket set once, and keep using it in
the CheckSockets() call.

See ya!
-Sam Lantinga (slouken at devolution.com)


Author of Simple DirectMedia Layer -
http://www.devolution.com/~slouken/SDL/