• Advertisement

Archived

This topic is now archived and is closed to further replies.

(Probably) Simple Problem with SDL_Net + UDP sockets

This topic is 5103 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I'm trying to test out SDL_Net between my MacOSX box and my PC, and I think I've got the thing SENDING just fine. My problem is with receiving. I've written 2 simple applications, one for sending and one for receiving (code below). Currently, I'm running the 'send' app on my PC with IP address 192.168.0.1 and the 'recv' app on my mac with IP address 192.168.0.5 (simple things stripped down to the bare essentials). The two machines can ping each other just fine, and when I reverse the scenario (recv on PC and send on mac) my little network lights go blinky blink just fine. Also, in that same reversed scenario if I run WinDump on my PC and track packets from the mac's IP, it will pop up with: IP 192.168.0.5.10005 > 192.168.0.1.10001: udp 14 for each packet. The sending app will always send the packets just fine, but the receiving app just waits forever, awaiting death poor and lonely. I'm using SDL_Net v 1.2.5 send.cpp
#define PLATFORM_W32 // supports either DirectX or OpenGL via DLL

//#define PLATFORM_OSX // mac OSX (using SDL+OpenGL)


#include <iostream>
#include <string>

#if defined(PLATFORM_W32)
	#pragma comment ( lib, "SDL_net.lib" )
	#pragma comment ( lib, "SDL.lib" )
	#pragma comment ( lib, "SDLmain.lib" )

	#include <windows.h>
	#include <SDL.h>
	#include <SDL_main.h>
	#include <SDL_net.h>
#elif defined(PLATFORM_OSX)
	#include <SDL.h>
	#include <SDL_net.h>
#else 
#error bad platform
#endif

int main(int argc, char *argv[])
{
	//////////

	// vars //

	//////////


	std::string text = "I am a packet!";

	std::string localIP   = "192.168.0.1";
	std::string foreignIP = "192.168.0.5"; 

	UDPsocket l_SendSocket;

	IPaddress l_LocalIPaddr,
		      l_ForeignIPaddr;

	int l_SendChannel;

	Uint16	l_LocalPort     = 10001,
	        l_ForeignPort   = 10005;

	/////////////

	// startup //

	/////////////


	SDL_Init(0);

	if(SDLNet_Init() != 0)
	{
		std::cout << "SDLNet_Init() failed: " << SDLNet_GetError() << std::endl;
		return 1;
	}
	std::cout << "Network started." << std::endl;

	SDLNet_ResolveHost(&l_LocalIPaddr, localIP.c_str(), l_LocalPort);
	SDLNet_ResolveHost(&l_ForeignIPaddr, foreignIP.c_str(), l_ForeignPort);

	Uint32 ipval = l_LocalIPaddr.host;
	Uint16 portval = l_LocalIPaddr.port;
	unsigned char a,b,c,d;

#if defined(PLATFORM_W32)
	d = ipval >> 24;
	c = ipval >> 16;
	b = ipval >> 8;
	a = ipval;
#elif defined(PLATFORM_OSX)
	d = ipval;
	c = ipval >> 8;
	b = ipval >> 16;
	a = ipval >> 24;
#else
#error fix me
#endif

	std::cout << "Sending data from " << (int)a << "." << (int)b << "." << 
		(int)c << "." << (int)d << ":" << (int)portval;

	ipval = l_ForeignIPaddr.host;
	portval = l_ForeignIPaddr.port;
#if defined(PLATFORM_W32)
	d = ipval >> 24;
	c = ipval >> 16;
	b = ipval >> 8;
	a = ipval;
#elif defined(PLATFORM_OSX)
	d = ipval;
	c = ipval >> 8;
	b = ipval >> 16;
	a = ipval >> 24;
#else
#error fix me
#endif

	std::cout << " to " << (int)a << "." << (int)b << "." << (int)c << "." << 
		(int)d << ":" << (int)portval << std::endl;


	////////////////////

	// enable sending //

	////////////////////


	l_SendSocket = SDLNet_UDP_Open(l_LocalPort);
	if(!l_SendSocket)
	{
		std::cout << "Failed to open socket for send off port " << l_LocalPort << std::endl;
		return 1;
	}
	
	l_SendChannel = SDLNet_UDP_Bind(l_SendSocket, 0, &l_ForeignIPaddr);
	if(l_SendChannel == -1)
	{
		std::cout << "Failed to bind socket for send off port " << l_LocalPort << std::endl;
		return 1;
	}
	std::cout << "Successfully bound channel " << l_SendChannel << " for send." << std::endl;


	///////////////

	// send loop //

	///////////////


	// pause for 10 seconds so I have time to start the receiver

	SDL_Delay(10000);

	
	int packetsLeft=10;

	while(packetsLeft > 0)
	{
		UDPpacket* packet;
		int numsent;
		
		packet = SDLNet_AllocPacket((int)text.length());
		packet->channel = l_SendChannel;
		packet->len = (int)text.length();
		packet->address = l_LocalIPaddr;

		memcpy(packet->data, text.c_str(), text.length());

		numsent = SDLNet_UDP_Send(l_SendSocket, packet->channel, packet);

		if(!numsent)
		{
			std::cout << "Failed to send packet: " << SDLNet_GetError() << std::endl;
		}
		else
		{
			std::cout << "packet sent: " << packet->data << std::endl;
		}
	
		SDLNet_FreePacket(packet);	

		packetsLeft--;
		SDL_Delay(1000);
	}

	/////////////////////

	// disable sending //

	/////////////////////


	SDLNet_UDP_Unbind(l_SendSocket, l_SendChannel);
	
	SDLNet_UDP_Close(l_SendSocket);


	/////////////

	// cleanup //

	/////////////


	SDLNet_Quit();
	std::cout << "\nNetwork stopped.\n\n\n";

	SDL_Quit();

	return 0;
}
recv.cpp
//#define PLATFORM_W32 // supports either DirectX or OpenGL via DLL

#define PLATFORM_OSX // mac OSX (using SDL+OpenGL)


#include <iostream>
#include <string>

#if defined(PLATFORM_W32)
	#pragma comment ( lib, "SDL_net.lib" )
	#pragma comment ( lib, "SDL.lib" )
	#pragma comment ( lib, "SDLmain.lib" )

	#include <windows.h>
	#include <SDL.h>
	#include <SDL_main.h>
	#include <SDL_net.h>
#elif defined(PLATFORM_OSX)
	#include <SDL.h>
	#include <SDL_net.h>
#else 
#error bad platform
#endif

int main(int argc, char *argv[])
{
	//////////

	// vars //

	//////////


	std::string localIP   = "192.168.0.5";
	std::string foreignIP = "192.168.0.1"; 

	UDPsocket l_ListenSocket;

	IPaddress l_LocalIPaddr,
		      l_ForeignIPaddr;

	int l_ReceiveChannel;

	Uint16	l_LocalPort     = 10005,
	        l_ForeignPort   = 10001;

	/////////////

	// startup //

	/////////////


	SDL_Init(0);

	if(SDLNet_Init() != 0)
	{
		std::cout << "SDLNet_Init() failed: " << SDLNet_GetError() << std::endl;
		return 1;
	}
	std::cout << "Network started." << std::endl;

	SDLNet_ResolveHost(&l_LocalIPaddr, localIP.c_str(), l_LocalPort);
	SDLNet_ResolveHost(&l_ForeignIPaddr, foreignIP.c_str(), l_ForeignPort);

	Uint32 ipval = l_LocalIPaddr.host;
	Uint16 portval = l_LocalIPaddr.port;
	unsigned char a,b,c,d;

#if defined(PLATFORM_W32)
	d = ipval >> 24;
	c = ipval >> 16;
	b = ipval >> 8;
	a = ipval;
#elif defined(PLATFORM_OSX)
	d = ipval;
	c = ipval >> 8;
	b = ipval >> 16;
	a = ipval >> 24;
#else
#error fix me
#endif

	std::cout << (int)a << "." << (int)b << "." << (int)c << "." << (int)d 
		<< ":" << (int)portval << " receiving data from ";

	ipval = l_ForeignIPaddr.host;
	portval = l_ForeignIPaddr.port;
#if defined(PLATFORM_W32)
	d = ipval >> 24;
	c = ipval >> 16;
	b = ipval >> 8;
	a = ipval;
#elif defined(PLATFORM_OSX)
	d = ipval;
	c = ipval >> 8;
	b = ipval >> 16;
	a = ipval >> 24;
#else
#error fix me
#endif

	std::cout << (int)a << "." << (int)b << "." << (int)c << "." << 
		(int)d << ":" << (int)portval << std::endl;


	///////////////////

	// enable listen //

	///////////////////


	l_ListenSocket = SDLNet_UDP_Open(l_LocalPort);
	if(!l_ListenSocket)
	{
		std::cout << "Failed to open socket for listen off port " << l_LocalPort << std::endl;
		return 1;
	}
	
	l_ReceiveChannel = SDLNet_UDP_Bind(l_ListenSocket, 0, &l_ForeignIPaddr);
	if(l_ReceiveChannel == -1)
	{
		std::cout << "Failed to bind socket for receive off port " << l_LocalPort << std::endl;
		return 1;
	}
	std::cout << "Successfully bound channel " << l_ReceiveChannel << " for receive." << std::endl;


	///////////////

	// recv loop //

	///////////////


	int packetsLeft=1;

	// immediately start checking for packets

	while(packetsLeft > 0)
	{
		/////////////

		// receive //

		/////////////


		UDPpacket* inPacket = NULL;

        int numrecv;

		numrecv = SDLNet_UDP_Recv(l_ListenSocket, inPacket);
		if(numrecv)
		{
			std::cout << "packet received: " << (char*)inPacket->data << std::endl;
			packetsLeft--;
		}
	}

	/////////////////////

	// disable receive //

	/////////////////////


	SDLNet_UDP_Unbind(l_ListenSocket, l_ReceiveChannel);
	
	SDLNet_UDP_Close(l_ListenSocket);


	/////////////

	// cleanup //

	/////////////


	SDLNet_Quit();
	std::cout << "\nNetwork stopped.\n\n\n";

	SDL_Quit();

	return 0;
}
Anybody who can help gets 4 points. Thanks! (also, if this needs to go in the beginners' section feel free to move it). Edit: could have sworn the tag was code and not source. [edited by - denJeebus on March 5, 2004 6:07:07 PM]

Share this post


Link to post
Share on other sites
Advertisement
By the by, a few more points:

I''m about to test this from Windows <-> Windows to see if there might be an endianness issue (there shouldn''t be).

Currently I don''t even care about what''s in the packet at all, I just want the system to recognize that a packet has been received.

In fact, I don''t even care I or anybody else can get these applications to work, I''d be happy enough with a UDP socket tutorial that uses SDL_Net.

One thing, though: I don''t want to use the NET2 library (built on top of SDL_Net) since I don''t think it supports OSX yet and I need support for Windows and OSX for my current project.

Share this post


Link to post
Share on other sites
Hmmm, I guess the ''probably'' was right.

Here''s how I fixed my stupid friggin'' problem.

In recv.cpp, I moved the inPacket declaration to right before the while loop. I then added the following:


inPacket = SDLNet_AllocPacket(1024);

// while loop goes here


SDLNet_FreePacket(inPacket);



And that was it! Apparently the SDLNet_UDP_Recv() function doesn''t size the packet for you (this speeds things up, I''m sure).

Share this post


Link to post
Share on other sites

  • Advertisement