SDL_NET sending problem

Hi, I’m currently writing an SDL_Net program, which shall send an integer at a specific time to all connected clients.
This works so far, but when a client disconnects, the program quits(broken pipe).
Here is my sourcecode:

#include <SDL/SDL.h>
#include <SDL/SDL_net.h>
#include
#include
using namespace std;

class client
{
public:
IPaddress ip;
TCPsocket sock;
};

int main(int argc, char* argv[] )
{
TCPsocket sd,csd;
IPaddress ip,*remoteIP;
list cls;
int buffer;
unsigned int result;
buffer=1;

if(!SDLNet_Init() == -1)
{
	cerr << "Could not init SDL_Net: " << SDLNet_GetError() << endl;
	return false;
}
if(SDLNet_ResolveHost(&ip, NULL, 6784))
{
	cerr << "SDLNet_ResolveHost: " << SDLNet_GetError() << endl;
	return false;
}
if (!(sd = SDLNet_TCP_Open(&ip)))
{
	cerr << "SDLNet_TCP_Open: " << SDLNet_GetError() << endl;
	return false;
}
while(true)
{
	if((csd=SDLNet_TCP_Accept(sd)))
	{
		if ((remoteIP = SDLNet_TCP_GetPeerAddress(csd)))
		{
			client temp;
			temp.ip=*remoteIP;
			temp.sock=csd;
			cls.push_back(temp);
		}
		else
			cerr << "SDLNet_TCP_GetPeerAddress: %s\n"<< SDLNet_GetError()<<endl;
	}
	for(int i=0;i<256;i++)
	{
		usleep(60000000/120/64);
		buffer=i;
		if(!cls.empty())
		{
			list<client>::iterator iter = cls.begin();
			for(iter = cls.begin(); iter != cls.end(); iter++)
			{
				result=SDLNet_TCP_Send(iter->sock, (void *)&buffer, sizeof(buffer));
				cout << "send " << result << "\n" << SDLNet_GetError() << endl;
				if(result < sizeof(buffer))
				{
					cout << "client discsonnected\n";
					SDLNet_TCP_Close(iter->sock);
					cls.erase(iter);
				}
			}
		}
	}
}
return 0;

}

As you see, I handle the return of SDL_Net_TCP_Send, but it is useless as I never get into th if function.
I hope you see the problem and thanks for your help.–
This was a Golden Age, a time of high adventure, rich living, and hard
dying… but nobody thought so. This was a future of fortune and theft,
pillage and rapine, culture and vice… but nobody admitted it.
– Alfred Bester, “The Stars My Destination”

Hi, I’m currently writing an SDL_Net program, which shall send an integer at a specific time to all connected clients.
This works so far, but when a client disconnects, the program quits(broken pipe).

You need to catch the signal something like this:

signal(SIGPIPE, SIG_IGN);

I got that line from the net2 library.

Here is my sourcecode:

Here is the source code and documentation.
http://gameprogrammer.com/net2/net2-0.html

The library really solves all these problem for you. It will give you an
SDL event when there is data ready to receive and a different event when
a client disconnects for any reason. Try it, many people like it.

	Bob PendletonOn Wed, 2006-04-19 at 13:37 +0200, krampenschiesser at freenet.de wrote:

#include <SDL/SDL.h>
#include <SDL/SDL_net.h>
#include
#include
using namespace std;

class client
{
public:
IPaddress ip;
TCPsocket sock;
};

int main(int argc, char* argv[] )
{
TCPsocket sd,csd;
IPaddress ip,*remoteIP;
list cls;
int buffer;
unsigned int result;
buffer=1;

if(!SDLNet_Init() == -1)
{
cerr << "Could not init SDL_Net: " << SDLNet_GetError() << endl;
return false;
}
if(SDLNet_ResolveHost(&ip, NULL, 6784))
{
cerr << "SDLNet_ResolveHost: " << SDLNet_GetError() << endl;
return false;
}
if (!(sd = SDLNet_TCP_Open(&ip)))
{
cerr << "SDLNet_TCP_Open: " << SDLNet_GetError() << endl;
return false;
}
while(true)
{
if((csd=SDLNet_TCP_Accept(sd)))
{
if ((remoteIP = SDLNet_TCP_GetPeerAddress(csd)))
{
client temp;
temp.ip=*remoteIP;
temp.sock=csd;
cls.push_back(temp);
}
else
cerr << “SDLNet_TCP_GetPeerAddress: %s\n”<< SDLNet_GetError()<<endl;
}
for(int i=0;i<256;i++)
{
usleep(60000000/120/64);
buffer=i;
if(!cls.empty())
{
list::iterator iter = cls.begin();
for(iter = cls.begin(); iter != cls.end(); iter++)
{
result=SDLNet_TCP_Send(iter->sock, (void *)&buffer, sizeof(buffer));
cout << "send " << result << “\n” << SDLNet_GetError() << endl;
if(result < sizeof(buffer))
{
cout << “client discsonnected\n”;
SDLNet_TCP_Close(iter->sock);
cls.erase(iter);
}
}
}
}
}
return 0;
}

As you see, I handle the return of SDL_Net_TCP_Send, but it is useless as I never get into th if function.
I hope you see the problem and thanks for your help.


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

Thank you! It works.
I’ve already looked at sdl_net2, but it needs video mode, which my programs don’t have.
Gui and internal programm are seperated as client and server.
Scar–
Technology is dominated by those who manage what they do not understand.

Under Unices, your process receives a signal SIGPIPE when it trys to write into a closed/invalid socket/file/pipe/file descriptor.
This signal is handled by a default handler, which exit() by default.
You could redirect SIGPIPE signal handler or set it to SIG_IGN in your case

reference to check (depending on your OS):
man signal
man sigaction

krampenschiesser at freenet.de a ?crit :> Hi, I’m currently writing an SDL_Net program, which shall send an integer at a specific time to all connected clients.

This works so far, but when a client disconnects, the program quits(broken pipe).
Here is my sourcecode:

#include <SDL/SDL.h>
#include <SDL/SDL_net.h>
#include
#include
using namespace std;

class client
{
public:
IPaddress ip;
TCPsocket sock;
};

int main(int argc, char* argv[] )
{
TCPsocket sd,csd;
IPaddress ip,*remoteIP;
list cls;
int buffer;
unsigned int result;
buffer=1;

if(!SDLNet_Init() == -1)
{
cerr << "Could not init SDL_Net: " << SDLNet_GetError() << endl;
return false;
}
if(SDLNet_ResolveHost(&ip, NULL, 6784))
{
cerr << "SDLNet_ResolveHost: " << SDLNet_GetError() << endl;
return false;
}
if (!(sd = SDLNet_TCP_Open(&ip)))
{
cerr << "SDLNet_TCP_Open: " << SDLNet_GetError() << endl;
return false;
}
while(true)
{
if((csd=SDLNet_TCP_Accept(sd)))
{
if ((remoteIP = SDLNet_TCP_GetPeerAddress(csd)))
{
client temp;
temp.ip=*remoteIP;
temp.sock=csd;
cls.push_back(temp);
}
else
cerr << “SDLNet_TCP_GetPeerAddress: %s\n”<< SDLNet_GetError()<<endl;
}
for(int i=0;i<256;i++)
{
usleep(60000000/120/64);
buffer=i;
if(!cls.empty())
{
list::iterator iter = cls.begin();
for(iter = cls.begin(); iter != cls.end(); iter++)
{
result=SDLNet_TCP_Send(iter->sock, (void *)&buffer, sizeof(buffer));
cout << "send " << result << “\n” << SDLNet_GetError() << endl;
if(result < sizeof(buffer))
{
cout << “client discsonnected\n”;
SDLNet_TCP_Close(iter->sock);
cls.erase(iter);
}
}
}
}
}
return 0;
}

As you see, I handle the return of SDL_Net_TCP_Send, but it is useless as I never get into th if function.
I hope you see the problem and thanks for your help.

signal(SIGPIPE, SIG_IGN);

This has been added to SDL_net in CVS, thanks!

-Sam Lantinga, Senior Software Engineer, Blizzard Entertainment

Thank you! It works.
I’ve already looked at sdl_net2, but it needs video mode, which my programs don’t have.

Just use the dummy video driver and all is good.

Bob PendletonOn Wed, 2006-04-19 at 23:01 +0200, krampenschiesser at freenet.de wrote:

Gui and internal programm are seperated as client and server.
Scar

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

signal(SIGPIPE, SIG_IGN);

This has been added to SDL_net in CVS, thanks!

Say what! I complained about that bug years ago and now you fix it? Oh
my… ROFLMAO!

If I complain about the lack of a ready to write flag will you fix that
too? Please? :slight_smile:

Bob PendletonOn Thu, 2006-04-20 at 09:48 -0700, Sam Lantinga wrote:

-Sam Lantinga, Senior Software Engineer, Blizzard Entertainment


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


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

Would you accept a patch to add something like
SDLNet_TCP_SetNonblockingReads(TCPSocket) if I were to write one?

Currently we are using intimate knowledge of SDL_Net’s structures combined
with platform specific hackery to do it on Windows / BSD sockets /
OpenTransport. Very nasty.

If set, SDLNet_TCP_Recv could return 0 and it wouldn’t be an error.

GregoryOn Thu, 20 Apr 2006, Sam Lantinga wrote:

signal(SIGPIPE, SIG_IGN);

This has been added to SDL_net in CVS, thanks!

-Sam Lantinga, Senior Software Engineer, Blizzard Entertainment


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

signal(SIGPIPE, SIG_IGN);

This has been added to SDL_net in CVS, thanks!

Say what! I complained about that bug years ago and now you fix it? Oh
my… ROFLMAO!

grin You have to remind me! :slight_smile:

If I complain about the lack of a ready to write flag will you fix that
too? Please? :slight_smile:

Sure, as long as you provide a patch, and test it on UNIX and Win32,
and let me know if anything needs to be done for Open Transport. :slight_smile:

Heheh
-Sam Lantinga, Senior Software Engineer, Blizzard Entertainment> On Thu, 2006-04-20 at 09:48 -0700, Sam Lantinga wrote:

signal(SIGPIPE, SIG_IGN);

This has been added to SDL_net in CVS, thanks!

Say what! I complained about that bug years ago and now you fix it? Oh
my… ROFLMAO!

grin You have to remind me! :slight_smile:

If I complain about the lack of a ready to write flag will you fix that
too? Please? :slight_smile:

Sure, as long as you provide a patch, and test it on UNIX and Win32,
and let me know if anything needs to be done for Open Transport. :slight_smile:

Ok folks, the gauntlet has been thrown down, are there any win32 and Mac
programmers who would like to collaborate on an improved SDL_Net?

Heheh
-Sam Lantinga, Senior Software Engineer, Blizzard Entertainment

Hehheh my ass… :slight_smile:

	Bob PendletonOn Thu, 2006-04-20 at 11:52 -0700, Sam Lantinga wrote:

On Thu, 2006-04-20 at 09:48 -0700, Sam Lantinga wrote:


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


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

Ok folks, the gauntlet has been thrown down, are there any win32 and Mac
programmers who would like to collaborate on an improved SDL_Net?

I can contribute two patches for things Aleph One needs in SDL_Net, and
currently does on its own: optional non-blocking TCP reads, and the
ability to send UDP packets to the broadcast address on all interfaces
(although I don’t have OT code for the latter one yet).

I don’t know how lightweight SDL_Net is intended to be, though :slight_smile:

I also have build environments set up for Windows / BSD sockets /
OpenTransport, so I could help with those.

GregoryOn Thu, 20 Apr 2006, Bob Pendleton wrote:

I can contribute two patches for things Aleph One needs in SDL_Net, and
currently does on its own: optional non-blocking TCP reads, and the
ability to send UDP packets to the broadcast address on all interfaces

But please let the blocking tcp reads be available.
I need them for my app :POn Thu, 20 Apr 2006 15:37:49 -0400 (EDT) Gregory Smith wrote:


Nuclear powered vacuuum cleaners will probably be a reality within 10 years.
– Alex Lewyt (President of the Lewyt Corporation,
manufacturers of vacuum cleaners), quoted in The New York
Times, June 10, 1955.

signal(SIGPIPE, SIG_IGN);

This has been added to SDL_net in CVS, thanks!

Say what! I complained about that bug years ago and now you fix it? Oh
my… ROFLMAO!

grin You have to remind me! :slight_smile:

If I complain about the lack of a ready to write flag will you fix that
too? Please? :slight_smile:

That would be cool.

Sure, as long as you provide a patch, and test it on UNIX and Win32,
and let me know if anything needs to be done for Open Transport. :slight_smile:

I can test a patch on those platforms (I’ve got a box of UNIX on a
shelf somewhere).> From: Sam Lantinga

On Thu, 2006-04-20 at 09:48 -0700, Sam Lantinga wrote: