Sign in to follow this  
etsuja

simple client/server problems

Recommended Posts

I'm trying to make a simple client and server with UDP but am running into issues. Here's what I'm doing. I get the server setup fine and loop a recvfrom() function. Then I run my client which calls a sendto() function however my server never recieves anything if anyone could help it would be much appreciated. Here's some of my code On my server this function is called at initialisation
void SetupLoginConnection()
{

	int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
	if ( iResult != NO_ERROR )
	{
		AddString(TEXT("Error at WSAStartup()"));
	}

	
	UDPSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP);

	if ( UDPSocket == INVALID_SOCKET ) 
	{
		AddString(TEXT("Error at socket():"));
		closesocket(UDPSocket);
		WSACleanup();
		return;
	}

	sockaddr_in service;

	hp = gethostbyname("localhost");

	service.sin_family = AF_INET;
	service.sin_addr.s_addr = inet_addr("127.0.0.1");
	service.sin_port = htons(32459);

	if ( bind( UDPSocket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR )
	{
		AddString(TEXT("bind() failed."));
		closesocket(UDPSocket);
		WSACleanup();
		return;
	}

	AddString(TEXT("Waiting for request on port:"));
	
}

Then this function is called in the main server loop
void SendRcv()
{

	char inbuffer[256];
	int test;
	int len = sizeof(SOCKADDR);
	memset(inbuffer, '\0', 256);
	if(test = recvfrom(UDPSocket, inbuffer, 256, 0, NULL, &len) >= 0)
	{
		AddString(TEXT("Packets recieved!"));
		MessageBox(NULL, NULL, TEXT("Incoming Data"), MB_OK);

	}
	if(test == SOCKET_ERROR)
	{
		MessageBox(NULL, NULL, TEXT("FUCK!!"), MB_OK);
	}

}


Now here's my client main function
int _tmain(int argc, char* argv[])
{

	int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
	if ( iResult != NO_ERROR )
	{
		printf("error");
	}
		
	UDPSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP);

	if ( UDPSocket == INVALID_SOCKET ) 
	{
		printf("socket error");
		WSACleanup();
		return 1;
	}

	sockaddr_in service;

	service.sin_family = AF_INET;
	service.sin_addr.s_addr = inet_addr("127.0.0.1");
	service.sin_port = htons(32459);

	char buffer[256];
	int len = sizeof(SOCKADDR);
	int test;
	strcpy(buffer,"HELLO!!!");
	test = sendto(UDPSocket, buffer, sizeof(buffer), 0, (SOCKADDR *)&service, sizeof(SOCKADDR));
	if(test == SOCKET_ERROR)
	{
		printf("no data sent");
	}

	if((test == SOCKET_ERROR) || (test < 0))
	{
		printf("FUCK!!");
	}
	else
	{
		printf("%s sent",buffer);
	}

	closesocket(UDPSocket);
	WSACleanup();
	return 0;
}


Share this post


Link to post
Share on other sites
I think this is similar to a recent question: if you bind the socket to 127.0.0.1, only requests from that address will be allowed. You should bind to 'all sockets', a C programmer can come on and say what the appropriate constant is.

Share this post


Link to post
Share on other sites
I changed the server address to INADDR_ANY and changed my clients address to my external internet address and my firewall asks me if I want to allow my client to access the internet on the right destination address and port then it asks me if I want to allow the server to accept connections from the internet and source address is right but the port seems to be different everytime I run it.

Share this post


Link to post
Share on other sites
The actual port given to a UDP socket if you don't bind it is undefined (i.e. the OS can give you whatever it likes). However, you can identify the client by the IP/port combination it shows up as, and you can send data back to the client by using that information with sendto. If you send multiple packets from one client they should all report the same.

To enable bidirectional communication via UDP on a particular port, you need to bind a socket at both ends. I don't know whether you can use the same socket for bind/recvfrom and sendto, as I'm not a UDP man myself.

But in short, you should expect the port reported by the 'server' end of a UDP connection to be variable. The IP/port combination identifies a client.

(edited for lies)

Share this post


Link to post
Share on other sites
well I found the problem, I'm getting a socket error it's WSAEPROTOTYPE which means wrong protocal for socket type. I don't understand why it's not working if IPPROTO_UDP is the wrong protocal for SOCK_DGRAM I don't know what the hell I'm supposed to do.

Share this post


Link to post
Share on other sites
I just realized I don't have the microsoft platform sdk installed, I'm guessing that's why I'm having these problems. I'll see if it works after I install it

Share this post


Link to post
Share on other sites
Quote:
Original post by Bob Janova
... I don't know whether you can use the same socket for bind/recvfrom and sendto, as I'm not a UDP man myself...


Yes, you can.



Share this post


Link to post
Share on other sites
it's still doing it, I'm gonna kill someone if it keeps doing this. I even tried changing the socket to tcp using socket type SOCK_STREAM and protocal IPPROTO_TCP and it's giving me the same error. wth?

Is it possible because I get a first chance exception when UDPSocket is defined?

UDPSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP);

gives me a first chance exception for some reason.

Share this post


Link to post
Share on other sites
Ok, it sounds like you're going to run into some routing issues.

Here's what you should have:

1) Your server should be bound to INADDR_ANY, and a FIXED PORT (eg 6969).

2) Your client should NOT be bound, and should NOT specify an address. Just create a datagram socket. It only needs to be tracked on the server, where it can be identified by its unique IP and port.

3) Your router should expose its external IP address at the fixed port specified by the server (eg 6969) and should forward UDP packets to your server's INTERNAL IP, at the specified port.

You can now connect to your server from inside the network by specifying it's LAN address and the port, and from outside by specifying your router's external IP and the port. Note that depending on your router, you may not be able to access 'as if from outside', and may have to use the local IP for testing.

EDIT: It looks like you're creating the socket correctly. Are you linking and including the correct winsock library and headers? Winsock 2 I believe has to be included BEFORE windows.h or weird stuff happens.

Share this post


Link to post
Share on other sites
The Line:

if(test = recvfrom(UDPSocket, inbuffer, 256, 0, NULL, &len) >= 0)

change to:

if((test = recvfrom(UDPSocket, inbuffer, 256, 0, NULL, &len)) >= 0)

NOTE: The added parens. Order of operations.

Share this post


Link to post
Share on other sites
I don't know if routing is an issue since I don't have a router. are they not getting packets since I don't have a send and a recieve in both of them? I tried putting winsock.h in head of the windows header and the same stuff happens and I'm linking to ws2_32.lib, is it possible it's not working because I'm trying it with the debug version?

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