SDL_net and socketpair

I’m porting my game to SDL_net.
Does anyone knows a way to emulate socketpair() with SDL net calls?

Thanx,
Francesco Orsenigo, Xarvh Project

Francesco Orsenigo wrote:

I’m porting my game to SDL_net.
Does anyone knows a way to emulate socketpair() with SDL net calls?

Thanx,
Francesco Orsenigo, Xarvh Project

open listen socket on a port,
open client socket,
connect client socket to listen socket port,
listen socket accepts client connection,

wahlah…–
-==-
Jon Atkins
http://jonatkins.org/

Jonathan Atkins:

open listen socket on a port,
open client socket,
connect client socket to listen socket port,
listen socket accepts client connection,

Ok, no alternative…
(i don’t like this 'cause is quit slow…)

Thanx,
Francesco Orsenigo, Xarvh Project

Francesco Orsenigo escribi?:

Jonathan Atkins:

open listen socket on a port,
open client socket,
connect client socket to listen socket port,
listen socket accepts client connection,

Ok, no alternative…
(i don’t like this 'cause is quit slow…)

Socketpair returns both socket descriptors, and is commonly followed by a
fork(). It serves as a commodity replacement for all the above (i.e. open
listen socket, open client socket, etc.) when the connection will take place on
a single machine, but AFAIK there’s no way to establish such a connection
between two different machines.

Regards,
Wizord.

Jos? Luis S?nchez:

Socketpair returns both socket descriptors, and is commonly followed by a
fork(). It serves as a commodity replacement for all the above (i.e. open
listen socket, open client socket, etc.) when the connection will take
place on a single machine,
Exactly what i do.
I use it for the “Create Game” feature of my game.
It is quite useful if you don’t want the host user to start both client and
dedicated server…
Why SDL_net has not such feature?
Should be useful to lots of game programmers…

Creating the 2 sockets with listen, accept and connect, may take several
seconds, is more complex and more likely to fail… socketpair() is much more
neat.

Francesco Orsenigo, Xarvh Project

Hi,

FO> Why SDL_net has not such feature?

Because it’s not portable. To be specific, it’s only available by
machines supporting the AF_UNIX address family. For whatever reason.

FO> Should be useful to lots of game programmers…

What’s the difference between that and doing it manually? All
it does is creating two sockets for you and return it in an array.

FO> Creating the 2 sockets with listen, accept and connect, may take several
FO> seconds, is more complex and more likely to fail… socketpair() is much more
FO> neat.

I’ll give you neater, but that’s your only valid point. You don’t
create sockets with listen, accept or connect, you’d have to use
socket() first anyway. Which is the same as socketpair(), except you
use a function call for each socket instead of one function that
returns two. So your point about it being more complex is marginal and
it’s no more likely to fail. And it won’t take several seconds longer
unless your compiler is worse than useless and takes that long to call
a function. :wink:

Even when using socketpair(), you still have to use listen, accept and
connect - socketpair() doesn’t know what you want to do with the
sockets! I don’t see your point at all - if you really want to use an
array of SOCKETs then you can quite easily. Just call socket() (or the
SDL_NET function, I use my own network routines) twice!

Neil.

Francesco Orsenigo escribi?:

Jos? Luis S?nchez:

Socketpair returns both socket descriptors, and is commonly followed by a
fork(). It serves as a commodity replacement for all the above (i.e. open
listen socket, open client socket, etc.) when the connection will take
place on a single machine,
Exactly what i do.
I use it for the “Create Game” feature of my game.
It is quite useful if you don’t want the host user to start both client and
dedicated server…
Why SDL_net has not such feature?
Should be useful to lots of game programmers…

Well, I don’t use SDL_net and I’m not sure why that call isn’t implemented, but
I can figure out it’s due to portability issues. socketpair is only supported
on Unix environments; it’s unsupported even on Windows (except CygWin).

OTOH, you can make use of shared memory if concerned about speed.

Regards,
Wizord.

Neil Griffiths <n.griffiths at virgin.net> escribi?:

FO> Creating the 2 sockets with listen, accept and connect, may take several
FO> seconds, is more complex and more likely to fail… socketpair() is much
FO> more neat.

I’ll give you neater, but that’s your only valid point. You don’t
create sockets with listen, accept or connect, you’d have to use
socket() first anyway. Which is the same as socketpair(), except you
use a function call for each socket instead of one function that
returns two. So your point about it being more complex is marginal and
it’s no more likely to fail. And it won’t take several seconds longer
unless your compiler is worse than useless and takes that long to call
a function. :wink:

Even when using socketpair(), you still have to use listen, accept and
connect - socketpair() doesn’t know what you want to do with the
sockets! I don’t see your point at all - if you really want to use an
array of SOCKETs then you can quite easily. Just call socket() (or the
SDL_NET function, I use my own network routines) twice!

Sorry but your point is not valid. socketpair is generally supported by a
special system call that does all the job. As the sockets aren’t really of TCP
domain, there is no need for listen, connect etc. and the kernel doesn’t do it
either.

Having said that, there’s only a marginal speed difference between socketpair
and their socket/listen/connect counterparts using AF_UNIX domain.

Regards,
Wizord.

Neil Griffiths:

I’ll give you neater, but that’s your only valid point. You don’t
create sockets with listen, accept or connect, you’d have to use
socket() first anyway. Which is the same as socketpair(), except you
use a function call for each socket instead of one function that
returns two. So your point about it being more complex is marginal and
it’s no more likely to fail. And it won’t take several seconds longer
unless your compiler is worse than useless and takes that long to call
a function. :wink:
Ehm, socketpair() creates a pair of INTERCONNECTED sockets.

Even when using socketpair(), you still have to use listen, accept and
connect
False.
I can socketpair(), fork() and then send() and recv() data back and forth
between parent and child.
Without any call to listen(), accept() or connect().

If you are saying that is possible to call socket() twice and then connect
somehow the two created sockets, tell me how (i’m new with network
programming) because it should do exactly what i need.

Regards,
Francesco Orsenigo, Xarvh Project

> > Having said that, there's only a marginal speed difference between socketpair > and their socket/listen/connect counterparts using AF_UNIX domain. > > Regards, > Wizord. > > _______________________________________________ > SDL mailing list > SDL at libsdl.org > http://www.libsdl.org/mailman/listinfo/sdl

I know this has already been mentioned, but I think it’s worth saying
again. If you’re already certain that the client is local, which you’d
have to be to use socket pair, or AF_UNIX for that matter, you’re
probably better off making a shared memory implementation anyway. It’ll
likely be faster than socketpair regardless of the system.

Maybe take a look at olofson’s sfifo: http://olofson.net/mixed.htmlOn Thu, 2002-09-05 at 12:25, Jos? Luis S?nchez wrote:

End of Rant.

Jimmy
Jimmy’s World (http://www.jimmysworld.org)
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20020905/cde0e27f/attachment.pgp

Hiya,

JLS> Sorry but your point is not valid. socketpair is generally supported by a
JLS> special system call that does all the job. As the sockets aren’t really of TCP
JLS> domain, there is no need for listen, connect etc. and the kernel doesn’t do it
JLS> either.

Then it’s not just socketpair() that’s wanted, but that wasn’t the
question. And my point was perfectly valid. You still need to use
socket() to create a socket, socketpair() creates a pair of sockets
for you. You need to pass across the type of data (TCP, Datagram etc)
for both functions. So my point is valid and you generally don’t have
one at all. :wink: I was using connect(), listen etc as examples of there
being no difference between calling socket() twice and using
socketpair().

As reference for socketpair():

http://www.mkssoftware.com/docs/man3/socketpair.3.asp
http://unixhelp.ed.ac.uk/CGI/man-cgi?socketpair+2

JLS> Having said that, there’s only a marginal speed difference between socketpair
JLS> and their socket/listen/connect counterparts using AF_UNIX domain.

Yes, I know. The overhead IS going to be calling socket() twice,
although this would be done by the system underneath the hood when
using socketpair() instead of the programmer themselves.

Neil.

Hello Francesco,

FO> Ehm, socketpair() creates a pair of INTERCONNECTED sockets.

Yes, but as I said before, it’s not portable. I’m showing you a
solution.

FO> False.
FO> I can socketpair(), fork() and then send() and recv() data back and forth
FO> between parent and child.
FO> Without any call to listen(), accept() or connect().

Not just by using socketpair() you can’t. If using TCP, you’d still
have to connect, else how does it know where to send the data? You
could use sendto() though with UDP.

FO> If you are saying that is possible to call socket() twice and then connect
FO> somehow the two created sockets, tell me how (i’m new with network
FO> programming) because it should do exactly what i need.

You don’t need to though, that’s my point. I’m showing you a perfectly
portable method - and have given you a reason why it’s not in SDL_net.
If you really, REALLY want to use interconnected sockets, use shared
memory, but I think that’s a really nasty solution. Doing something
like:

typedef struct {
SOCKET send;
SOCKET recv;
} sock_t;

is very similar to how you want, portable and just generally neater to
understand. And as fast. If you really need to share sockets, I would
suggest you re-think your design!

Neil.

Thinking further, it might be of benefit of putting a socketpair()
into SDL_net just for people, like Francesco, who want to use it -
and using my suggested fix so that it would work on Windows. I
don’t know whether MacOS or BeOS supports the call, I suspect BeOS
and Mac OS X would though…–
Best regards,
Neil mailto:n.griffiths at virgin.net

Neil Griffiths:

Not just by using socketpair() you can’t. If using TCP, you’d still
have to connect, else how does it know where to send the data? You
could use sendto() though with UDP.

The two sockets created with socketpair() acts just like two file descriptors
created with pipe() (but the two sockets are full-duplex, while the pipe
isn’t).
Both socketpair() and pipe() are useless unless the program forks().
In this way is possible to create a connection from the application to itself
(you send the data to yourself).
When you fork(), child closes one socket, parent closes the other: they’re
connected.
It works. I’ve been using it for months: i can exchange data between parent
and child without a single call to connect(), listen() and such.

typedef struct {
SOCKET send;
SOCKET recv;
} sock_t;

is very similar to how you want, portable and just generally neater to
understand. And as fast. If you really need to share sockets, I would
suggest you re-think your design!

I fork() the program.
Then I need parent and child to be connected so that they exchange data
through send() and recv().
THIS is what i need.

I’m feeling very stupid, but i can’t see how your struct can help me with
this.
Can you show me an example code, complete with the fork() call?

Thanx,
Francesco Orsenigo

Hiya,

typedef struct {
SOCKET send;
SOCKET recv;
} sock_t;

is very similar to how you want, portable and just generally neater to
understand. And as fast. If you really need to share sockets, I would
suggest you re-think your design!

FO> I fork() the program.
FO> Then I need parent and child to be connected so that they exchange data
FO> through send() and recv().
FO> THIS is what i need.

FO> I’m feeling very stupid, but i can’t see how your struct can help me with
FO> this.
FO> Can you show me an example code, complete with the fork() call?

Sure, something like this:

// Declared in your main code
sock_t main;

// Declared in your thread
sock_t thread;

Use listen(), then accept() on both main.recv and thread.recv and use
connect() to 127.0.0.1 on main.send and thread.send.

It’s not the greatest solution, but it’s portable, clean, and you
could use the same code to create a set of routines for handling any
network data too.

I’m assuming TCP here, but you could use datagrams. At least you know
that they’ll get to your own machine in the correct order and with
very little overhead!

I’m not at work right now so I don’t have any example code I could
quickly alter to demonstrate this, but that should work quite happily

  • and be portable and easier to understand (IMO) to boot.

Neil.

Neil Griffiths <n.griffiths at virgin.net> escribi?:

Hiya,

JLS> Sorry but your point is not valid. socketpair is generally supported by
JLS> a special system call that does all the job. As the sockets aren’t
JLS> really of TCP domain, there is no need for listen, connect etc. and the
JLS> kernel doesn’t do it either.

Then it’s not just socketpair() that’s wanted, but that wasn’t the
question. And my point was perfectly valid. You still need to use
socket() to create a socket, socketpair() creates a pair of sockets
for you. You need to pass across the type of data (TCP, Datagram etc)
for both functions. So my point is valid and you generally don’t have
one at all. :wink: I was using connect(), listen etc as examples of there
being no difference between calling socket() twice and using
socketpair().

Nonsense. socketpair creates a pair of sockets and connects them, and it
usually does it bypassing much of the overhead involved on normal sockets work.

OTOH, sockets created by socketpair don’t use TCP, datagrams and all that.
They are a different family of sockets (AF_UNIX) and only work on a single
machine (i.e. they don’t work across a network).

You can take a look at sys_socket and sys_socketpair syscalls on Linux kernel
and see the difference. socketpair is a very simple function whereas socket is
really complex.

http://www.mkssoftware.com/docs/man3/socketpair.3.asp
http://unixhelp.ed.ac.uk/CGI/man-cgi?socketpair+2

Hey, if you read carefully those man pages, you’ll see what I mean.

Regards,
Wizord.

Francesco Orsenigo escribi?:

I can socketpair(), fork() and then send() and recv() data back and forth
between parent and child.

This is the reason socketpair has sense only under Unix platforms. Windows
doesn’t support fork.

I mean, using Windows you can spawn a child process, but there’s no way for the
child process to inherit nor use the file descriptors from its parent.

Again, if you’re concerned about speed (and admitely the Windows TCP stack
isn’t by any means optimized for speed) you might consider the use of shared
memory. There are several multiplatform libraries for managing shared memory
out there.

Regards,
Wizord.

Neil Griffiths wrote:

Thinking further, it might be of benefit of putting a socketpair()
into SDL_net just for people, like Francesco, who want to use it -
and using my suggested fix so that it would work on Windows. I
don’t know whether MacOS or BeOS supports the call, I suspect BeOS
and Mac OS X would though…

Lets step back and think about this for a moment. I see why you would
want to use socketpair for the application that was mentioned. But, is
this really something to add to SDL_net? Or, should we be thinking about
an new library, SDL_process, that provides the functionality of fork,
exec, popen, and interprocess communication? I think we could come up
with a small set of APIs that are both portable and cover the need to
create processes and communicate with them. I guess what I’m saying is
that there isn’t much point in having a portable version of socketpair
if there isn’t a portable fork or popen or what not.

Personally, I would prefer an API like popen that gives me a
bidirectional connection to the new process. I know how to do that with
standard Unix APIs, but it would be so nice to have one simple API to do
the job.

	Bob Pendleton-- 

±-----------------------------------+

Hello Jos?,

JLS> Nonsense. socketpair creates a pair of sockets and connects them, and it
JLS> usually does it bypassing much of the overhead involved on normal sockets work.

That’s my mistake, I didn’t realise that the protocol was optional.

http://www.mkssoftware.com/docs/man3/socketpair.3.asp
http://unixhelp.ed.ac.uk/CGI/man-cgi?socketpair+2

JLS> Hey, if you read carefully those man pages, you’ll see what I mean.

Yes, as I said, I missed the fact that the protocol was optional. No
reason why my solution before couldn’t be used though to be
cross-platform - and it could actually use socketpair() on platforms
that support it properly.

Neil.

Bob Pendleton escribi?:

Personally, I would prefer an API like popen that gives me a
bidirectional connection to the new process. I know how to do that with
standard Unix APIs, but it would be so nice to have one simple API to do
the job.

Does anyone know of any way to emulate a fork() in Windows?

Oh, don’t bother. As a matter of fact all Windows versions routinely loses a
chunk of memory on every ended thread or process. Better don’t give a way to
fork too much or the system will quickly run out of memory. :wink:

Regards,
Wizord.