simple client/server problems

Started by
11 comments, last by etsuja 17 years, 11 months ago
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;
}


Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
Advertisement
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.
This was answered recently. The constant address is INADDR_ANY. Much of this is covered in Beej's guide.


Winterdyne Solutions Ltd is recruiting - this thread for details!
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.
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
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)
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.
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
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
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
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.



Winterdyne Solutions Ltd is recruiting - this thread for details!
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.
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
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.
Winterdyne Solutions Ltd is recruiting - this thread for details!

This topic is closed to new replies.

Advertisement