Sign in to follow this  
Westeria

I'm on the verge of giving up, please don't let me! (Broadcast Crisis)

Recommended Posts

Background: I'm currently working a MMORPG from my university residence. I've wrote the game, and I'm just getting the netcode to function properly. I understand that since I'm on a local LAN, my code will require changes if I'm to run it. So what I did was, I wrote my code to broadcast, and than I connected my roommates computer to mine using a crossover cable. When the program runs, it gives no errors, but no message boxes saying "Packet recieved" show up, ever since, I've been making minor changes to the netcode to get it working, and I think I might have changed it beyond repair: I'm on the verge of giving up! Because my project is soo large, I've only copied certian sections of the code. All the code is in strict procedural-c, and uses Winsock (1.1?) to do UDP. Please don't assume I know what I'm doing! [bawling] Server Code
#include "winsock.h"
#include "internet.h"
#include "main.h"
#include "data.h"

/* General Winsock Components */
int intVersion;
WSADATA localWSA; 
SOCKADDR_IN cliAddr, servAddr;
char tempBuff[300];
int intGlobalSocket;
int intStatus;
int intMode = 1;
int rc, n, cliLen;
struct hostent *h;
unsigned short i;
char a;
char chrParse1[10];
char chrParse2[10];

/* This procedure initializes the components required for Winsock to run! */
void sInitWinsock()
{
	int iOptVal;
	int iOptLen;

	intVersion = WSAStartup(MAKEWORD(1,1),&localWSA);
	intGlobalSocket = socket(AF_INET, SOCK_DGRAM, 0);
	if(intGlobalSocket == INVALID_SOCKET){ printf("Could not create socket!"); return;}
	
	servAddr.sin_family = AF_INET;
	getsockopt(intGlobalSocket, SOL_SOCKET, SO_BROADCAST, (char*)&iOptVal, &iOptLen);
	//servAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
	servAddr.sin_addr.s_addr = INADDR_ANY; // Internet Address
	servAddr.sin_port = htons(3012);    // Port Number 
	intStatus = bind(intGlobalSocket,(SOCKADDR *)&servAddr, sizeof(SOCKADDR_IN));
	if(intStatus == SOCKET_ERROR){ printf("Could not bind socket!"); return;}
	ioctlsocket(intGlobalSocket, FIONBIO, (u_long FAR*) &intMode); /*Sets the UDP to non blocking. */
	 servAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);

	
}

/* This procedure checks for any messages being sent to the server. */
void sCheckMessages()
{
	int intTotal = 0;
	unsigned short l;
	char chrTemp[2];
	int intPlayerID = 0;

	/* Clear The Buffer */
	memset(tempBuff,0x0,300);

	/* Receive the message (If it exists) */
	cliLen = sizeof(cliAddr);
	n = recvfrom(intGlobalSocket, tempBuff, 300, 0, (struct sockaddr *) &cliAddr, sizeof(cliAddr));

	if(n>0)
	{
		MessageBox(0,"Message REcieved","JAJAJ",0);
		/* Send the packet off to the account validation station for processing. :D */
		sValidate(tempBuff);
		intRecv += n;

		/* Reply to the kid. */
		for(l=0;l<1000;l++) if(arrObjects[l].bytUsed == 1) intTotal ++;
		memset(tempBuff,0x0,300);
		memcpy(tempBuff,arrObjects,intTotal * sizeof(struct strObject));
		memcpy(chrTemp,&intPlayerID,2);
		tempBuff[intTotal] = chrTemp[0];
		tempBuff[intTotal+1] = chrTemp[1];
		rc = sendto(intGlobalSocket, tempBuff , (intTotal*sizeof(struct strObject)) + 2, 0, 
		(struct sockaddr *) &cliAddr, 
		sizeof(cliAddr));
		intSent += (intTotal*sizeof(struct strObject)) + 2;
	}
}
Client Code
#include "main.h"
#include "physics.h"
#include "graphics.h"
#include "data.h"
#include "string.h"
#include "flags.h"
#include "ai.h"
#include "winsock.h"
#include "internet.h"


/* General Winsock Components */
/* (Its best not to try and understand all this.)*/
int intVersion;
WSADATA localWSA; 
SOCKADDR_IN cliAddr, servAddr;
char tempBuff[300];
int intGlobalSocket;
int intStatus;
int intMode = 1;
int rc, n, cliLen;
struct hostent *h;
unsigned short i;
char a;

/* This procedure initializes the components required for Winsock to run! */
void sInitWinsock()
{
		int iOptVal;
	int iOptLen;
	char chrHost[]="255.255.255.255";

	intVersion = WSAStartup(MAKEWORD(1,1),&localWSA);
	h = gethostbyname(chrHost);

	if(h==NULL){MessageBox(0,"Unknown host!","Error",0); return;}
	servAddr.sin_family = h->h_addrtype;
	servAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
	memcpy((char *) &servAddr.sin_addr.s_addr, 
	h->h_addr_list[0], h->h_length);
	servAddr.sin_port = htons(3012);
	


	intGlobalSocket = socket(AF_INET, SOCK_DGRAM, 0);
	if(intGlobalSocket == INVALID_SOCKET){ MessageBox(0,"Could not create socket!","Error",0); return;}
	cliAddr.sin_family = AF_INET;
	
	cliAddr.sin_addr.s_addr = INADDR_ANY; // Internet Address
	cliAddr.sin_port = htons(220);    // Port Number 
	intStatus = bind(intGlobalSocket,(SOCKADDR *)&cliAddr, sizeof(SOCKADDR_IN));
	if(intStatus == SOCKET_ERROR){ MessageBox(0,"Could not bind socket!","Error",0); return;}
	ioctlsocket(intGlobalSocket, FIONBIO, (u_long FAR*) &intMode); /*Sets the UDP to non blocking. */
	
	getsockopt(intGlobalSocket, SOL_SOCKET, SO_BROADCAST, (char*)&iOptVal, &iOptLen);
}

/* This procedure sends a message to the server. */
void sCheckMessages()
{
	unsigned short intByte;
	char chrTempBuff[2];
	/* Clear The Buffer */
	memset(tempBuff,0x0,300);

	/* Receive the message (If it exists) */
	n = recvfrom(intGlobalSocket, tempBuff, 300, 0, (struct sockaddr *) &cliAddr, sizeof(cliAddr));

	if(n>0)
	{

		MessageBox(0,"Message REcieved","JAJAJ",0);
		/* Unload the data into our creature slots! */
		memcpy(arrObjects,tempBuff, (n-2));
		chrTempBuff[0] = tempBuff[n-2];
		chrTempBuff[1] = tempBuff[n-1];
		memcpy(intLocalPlayer,chrTempBuff,2);
	}
}


/* This procedure sends movement request. */
void sSendMessage(char bytDirection)
{
	unsigned short l;

	/* Clear The Buffer */
	memset(tempBuff,0x0,300);

	/* Fill the username and password components. */
	memcpy(tempBuff,chrUsername,10);
	for(l=10;l<20;l++)
	{
		tempBuff[l] = chrPassword[l-10];
	}
	/* Send the message off */
	rc = sendto(intGlobalSocket, tempBuff,20, 0, 
	(struct sockaddr *) &servAddr, 
	sizeof(servAddr));
}
Again, I repeat. No message boxes pop up, the packets don't seem to get sent. Yet no error messages appear either. If anyone can solve this, they are genious: I've spent two full days trying to fix it, with no luck at all!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
It doesn't work, and it still doesn't give any errors. Meaning the server code, and the client code are both using different ports.

I'm going to switch both the ports to 3012 and do some more testing. But I believe its highly unlikey the ports were the only problem.

Share this post


Link to post
Share on other sites
Holy global variables batman!

server
------
You never setsockopt with SO_BROADCAST. I don't know why you're calling getsockopt instead.

Technically you should have htonl around INADDR_ANY. Not having it won't cause anything to break in this particular case though. For other addresses it will break (and you did use it for the commented-out INADDR_BROADCAST).

Since you set the socket to non-blocking sCheckMessages will probably never recieve anything unless you call it in a loop that you didn't include.

recvfrom should take a pointer to sizeof(cliAddr), not the size directly. If this isn't just a typo I'm surprised it compiled.

client
------
What's this business of gethostbyname("255.255.255.255")? Then you set s_addr and immediately overwrite it?

Just set servAddr.sin_family to AF_INET.

Clients don't usually bind to a specific port, just set the port to 0 and let the socket layer pick one for you. It shouldn't break anything for this small test though.

Again you're calling getsockopt for some reason but never setsockopt, and the non-blocking thing, and the recvfrom pointer thing. IMHO don't worry about trying to do non-blocking until you get blocking figured out.

You didn't turn on broadcast support (see above) yet you're still sending to 255.255.255.255 (a broadcast address). Either turn on broadcast support or for this test purpose send directly to the ip of the other machine. You can use inet_addr to convert a string with the dotted ip address to the appropriate s_addr (*don't* use gethostbyname with a dotted ip address).

Check the return value from sendto. I suspect it's giving you an error.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
All quotes from Anon Mike


Server Code.
Quote:
You never setsockopt with SO_BROADCAST. I don't know why you're calling getsockopt instead.

Yup. I switched all the getsockopt, to setsockop.

Quote:
Technically you should have htonl around INADDR_ANY. Not having it won't cause anything to break in this particular case though. For other addresses it will break (and you did use it for the commented-out INADDR_BROADCAST).

I don't really understand what you mean by this. As you describe later in your code, your helping me get it to with with Broadcast, but than you provide me with info that isn't broadcast coding.

Quote:
Since you set the socket to non-blocking sCheckMessages will probably never recieve anything unless you call it in a loop that you didn't include.

Yup, I had put it in a loop. [razz]

Quote:
recvfrom should take a pointer to sizeof(cliAddr), not the size directly. If this isn't just a typo I'm surprised it compiled.

I'm just as suprised.

Client Code
Quote:
What's this business of gethostbyname("255.255.255.255")? Then you set s_addr and immediately overwrite it?

I overrid it? Oops! The "255.255.255.255" is suppose to be the IP address for broadcasts... I had no clue I was overriding it!

Quote:
Just set servAddr.sin_family to AF_INET.
And than delete all the other stuff? I'm not sure what setting it to AF_INET actually does.

Quote:
You didn't turn on broadcast support (see above) yet you're still sending to 255.255.255.255 (a broadcast address). Either turn on broadcast support or for this test purpose send directly to the ip of the other machine. You can use inet_addr to convert a string with the dotted ip address to the appropriate s_addr (*don't* use gethostbyname with a dotted ip address). Check the return value from sendto. I suspect it's giving you an error.

gethostbyname doesn't work with dotted IP adresses?! Ack. Which varible to I set = to inet_addr("255.255.255.255"), I'm not quite sure the the addrcli.sfaimly code actually does, so any changes you say I should make, don't come quite readily understood by me.

However, you said I could send directly to the other machines IP address, even though the two computers are directly connect! Is this possible! The only reason I'm using broadcast is because I idn't know it was possible to address computesr on a LAN!


btw... your being very helpful![smile]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
omg, it works!!1 IT WORKS!!1

Ahuahuahuahauh!!11

I did exactly what you said, and I didn't even understand what you said, I just somehow knew where to put the values in. I got rid of the broadcasting too, and did a direct connection with the other computer.

Thank you soo much!11 It works soo perfectly!!1

I'm soo happy I'm like -->> [bawling] in RL!!!111

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this