Advertisement

UDP listening socket?

Started by July 16, 2005 08:59 AM
14 comments, last by hplus0603 19 years, 7 months ago
is it posible to have a listening udp socket? because mine allways fails. my tcp socket is fine, works great. i thought at first it might be because thay are both on the same port but i changed it and it still fails. any ideas? please help. thanks, Tom

WORD sockVersion;
	WSADATA wsaData;
	int nret;
	sockVersion = MAKEWORD(1, 1);			// We'd like Winsock version 1.1	
	WSAStartup(sockVersion, &wsaData);		// We begin by initializing Winsock
	listensock = socket(AF_INET,		// Go over TCP/IP
			         SOCK_STREAM,   	// This is a stream-oriented socket
				 IPPROTO_TCP);		// Use TCP rather than UDP
	if (listensock == INVALID_SOCKET) {
		return false; //FatalError( "Invalid socket!" );
	}	
	SOCKADDR_IN serverInfo; // Use a SOCKADDR_IN struct to fill in address information
	serverInfo.sin_family = AF_INET;
	serverInfo.sin_addr.s_addr = INADDR_ANY; // any local address will do
	serverInfo.sin_port = htons((u_short) port);		// Convert integer 8888 to network-byte order	
	nret = bind(listensock, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));// Bind the socket to our local server address
	if (nret == SOCKET_ERROR) {
		return false; //FatalError( "Socket error!" );
	}
	// Make the socket listen
	nret = listen(listensock, 10);		// Up to 10 connections may wait at any
							// one time to be accept()'ed

	if (nret == SOCKET_ERROR) {
		return false; //FatalError( "Socket error!" );
	}

	open = true;

	SOCKET tempudp = socket(AF_INET,		// Go over TCP/IP
			         SOCK_STREAM,   	// This is a stream-oriented socket
				 IPPROTO_UDP);		// Use TCP rather than UDP

	serverInfo.sin_port = htons((u_short) port+1);

	nret = bind( tempudp, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));// Bind the socket to our local server address
	if (nret == SOCKET_ERROR) {
		return false; 
	}
	
	nret = listen( tempudp, 10);							

	if (nret == SOCKET_ERROR) {
		return false;  <-- *** it allways returns here***
	}

	return true;
	
-www.freewebs.com/tm1rbrt -> check out my gameboy emulator ( worklog updated regularly )
No, you can't have a UDP listening socket. listen() (when used with TCP/IP) sets up details needed to handle the TCP handshaking. If you want to read from a UDP socket use recvfrom() without trying any of the connection scaffolding.
Advertisement
In my current network system i have a main listening socket. then when a socket connects to that it is copied to my client class... so each client has there own socket. i want each client to have a tcp and udp socket now.

how would i implement this? or can i do this?
-www.freewebs.com/tm1rbrt -> check out my gameboy emulator ( worklog updated regularly )
sorry. also note that i have to use Select() with the socket.
-www.freewebs.com/tm1rbrt -> check out my gameboy emulator ( worklog updated regularly )
If you want each client to have its own socket, you have to create a new socket, and bind it to some un-used port, and then inform the client of the new port number (this is similar to what TCP does, btw). Obviously, this won't work behind port forwarding or in server-behind-NAT set-ups.

What everyone ends up doing is to use a single socket for all UDP incoming, but use recvfrom(), and use a hash table to look up the intended recipient based on who sent the packet (perhaps use a client ID in the packet, too, for back-up if the remote UDP address changes -- but beware impostors!)

When you select() the UDP port for reading, you want to recvfrom() until there are no more packets, to avoid having to go through select() once per UDP packet on a high-load server. Usually, the socket is made non-blocking to make this easy.
enum Bool { True, False, FileNotFound };
Quote:
Original post by hplus0603

When you select() the UDP port for reading, you want to recvfrom() until there are no more packets, to avoid having to go through select() once per UDP packet on a high-load server. Usually, the socket is made non-blocking to make this easy.



Doh! I just realized I wasn't doing that in my own server. Thanks for mentioning that =)

-=[ Megahertz ]=-
-=[Megahertz]=-
Advertisement
allright...

so finaly - How do i have two udp sockets connect() to each other?
-www.freewebs.com/tm1rbrt -> check out my gameboy emulator ( worklog updated regularly )
bind() the server socket and connect() the client socket. Note that connecting to a remote UDP socket is nothing more than telling that socket to route all send() traffic to the specified endpoint, and discard any incoming packets that are not from the "connected" machine. As such, a UDP connect() should always succeed, even when the remote machine does not exist. It's up to the you to implement your own etiquette if you want true connections.
as Tim said connect will always return true.

When you try and read it will either fail or return NULL on no connection.
So you'll have to test the reads.
You can't bind() a UDP socket.

You can use connect() on a UDP socket, which means that you can call send() on it, and it will send to that specific address. You can use connect() on both sides. However, because UDP is not connection-oriented, you won't get any information if the other side exits.

Given that, most people just use recvfrom() and sendto() on the socket, without actually calling connect(); that way, you can use a single UDP socket for all communication you need to do in your process.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement