0

I am trying to run a simple program to read ethernet using UDP. Here is the code, but it always receives -1 for 'error', but I did it by the book. Do you guys see the problem? Thanks.

//enum specifying the current status of the comm port.
enum e_PortStatus
{
	PORT_BUSY,									//port is currently in use
	PORT_READY,									//port is setup and ready for communication
	PORT_ERROR									//an error has occured somewhere
};

e_PortStatus myPortStatus;

//methods
void InitializeDevice();					//method which sets up this class, called at startup
void SetupPort();							//method which readies the port for communications
void SendCommandToDevice();					//method which passes in parameters defining a message to be sent to the device on the port

static struct sockaddr_in mySocketAddress;			//used to keep track of the connector's address
static struct sockaddr_in theirSocketAddress;		//used to keep track of the connector's address
static int socket_fd;								//Socket File Descriptor
void StartDevice();									//Initializes the WINSOCK API
void CloseDevice();									//Close the WINSOCK API


void InitializeDevice()
{
	SetupPort();	
}

void SetupPort()
{
	int yes = 1;

	StartDevice();
	if (myPortStatus != PORT_READY)
		 CloseDevice();

	// create a UDP-based socket
	socket_fd = socket(PF_INET, SOCK_DGRAM, 0);
	if (socket_fd == -1) 
	{ 
		myPortStatus = PORT_ERROR;
		cout << "CANNOT CREATE SOCKET" << endl;
		CloseDevice();		
	}
	
	if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (char* )&yes, sizeof(int)) == -1)
	{
		cout << "setsockopt" << endl;
		CloseDevice();
	}

	// set up the local address 
	mySocketAddress.sin_family = AF_INET; 
	mySocketAddress.sin_port = htons(2010); //My_Port_Number
	mySocketAddress.sin_addr.s_addr = htonl(INADDR_ANY); //automatically fills in the IP address of the machine the process is running on

	// bind in socket to local address (sockaddr)
	if (bind(socket_fd, (sockaddr *) &mySocketAddress, sizeof (mySocketAddress)) == -1) 
	{ 
		myPortStatus = PORT_ERROR;
		cout << "CANNOT BIND SOCKET" << endl;
		int error = WSAGetLastError();
		CloseDevice();	
	}
}

char* ReceiveCommandFromDevice()
{
	char* messageBuf = NULL;
	int size_received;
	int dwtheirSocketAddressSize;

	/*Start of broadcast
	//Only use if you want to broadcast to every address on the network
	//So change theirSocketAddress.sin_addr.s_addr to INADDR_BROADCAST and uncomment
	if (setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, (char* )&broadcast, sizeof(broadcast)) == -1)
	{

		myPortStatus = PORT_ERROR;
		perror("setsockopt (SO_BROADCAST)");
		CloseDevice();
	
	}
	//end of broadcast

	*/

	//make sure Port is set to Ready Mode
	if ( myPortStatus == PORT_READY)
	{
		myPortStatus = PORT_BUSY;

		size_received = recvfrom(socket_fd, messageBuf, sizeof(messageBuf), MSG_WAITALL, (SOCKADDR*) &theirSocketAddress, &dwtheirSocketAddressSize);
		
		//check for error
		if (size_received == -1)
		{
			myPortStatus = PORT_ERROR;
			//cout << "CANNOT RECEIVE FROM PORT" << endl;
			CloseDevice();
			messageBuf = 'FAILURE';
		}
		else
			myPortStatus = PORT_READY;
	}

	return messageBuf;
}


void CloseDevice()
{
	closesocket(socket_fd);
	WSACleanup();
}

void StartDevice()
{
	WSADATA wsaData;
	int iResult;

	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

	if (iResult != 0) 
	{
		myPortStatus = PORT_ERROR;
		cout << "WSAStartup failed" << endl;
		CloseDevice();
	}
	else
		myPortStatus = PORT_READY; 
}


int _tmain(int argc, _TCHAR* argv[])
{
	InitializeDevice();

	char* message;

	while(1)
	{
		message = ReceiveCommandFromDevice();

		cout << "Received: " << message << endl << endl;

		Sleep(2000);
	}

	return 0;
}
2
Contributors
1
Reply
2
Views
9 Years
Discussion Span
Last Post by Salem
0

Probably because your use of messagebuf is broken in so many ways.

> size_received = recvfrom(socket_fd, messageBuf, sizeof(messageBuf),
messageBuf is NULL (1) and the sizeof is only the size of the pointer (2).
Since UDP is an "all-or-nothing" deal, if you can't fit the whole message into the space provided, then you don't get any of it. So any UDP packets larger than the typical 4-bytes for a pointer are just going to be dropped.

> messageBuf = 'FAILURE';
Please tell me your compiler told you this was bad?
Or do you just ignore all warnings and plough on until it crashes?

> int error = WSAGetLastError();
1. Add this to the call which fails.
2. Print it, so you know more.

Probably some other stuff, but that's enough for you to think about fixing.

And please don't just make messageBuf a char array and attempt to return it.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.