Hey y'all! I'm fairly new to internet programming, and I'm surrently developping my first socket app in Java.. Now I have a question... I wrote a simple chat client to learn the commands, it uses a datagram socket (that's what I want to stick with for now) and sends/recieves messages.. Everything is functioning perfectly, I'll optimize it as time goes on and use the knowledge forevermore.. But I want to know something, something that I couldn't fund using google...

When you use the command socket.receive(NewPacket); it blocks program execution until an actual socket is received, thus preventing me from doing anything (ie sending a message while waiting for incomming ones).. How do I prevent this? In Visual Basic, I would use the command DoEvents, but what about in Java? Can anybody help me listen for incomming packets without clogging CPU or halting the rest of the program from functioning??? THANK YOU!! Here is my Listen method as-is:

public void ListenForData() {
	// Recieve data

	while (true) {
		byte[] rcvm = new byte[MAXDATA];
		DatagramPacket NewPacket = new DatagramPacket(rcvm, rcvm.length);
		try {
			DGS.receive(NewPacket);
		} catch (Exception ex) {
			continue;
		}
		txtRecieved.append("Message from " + NewPacket.getAddress()
			+ ": " + new String(NewPacket.getData()) + "\n");
	}

}

Also, I am not too sure about exeception handelling here so if I can't do it with continue please let me know.

:cheesy:

Dani AI

Generated

— nice instinct to move the blocking receive() into a background thread; DatagramSocket.receive() blocks until a packet arrives, so keeping it off the main/UI thread is the correct approach. (docs.oracle.com)

One important follow-up: Swing GUI updates must happen on the Event Dispatch Thread (EDT). Appending to txtRecieved from your listener thread risks race conditions and odd UI behaviour. Schedule UI changes with SwingUtilities.invokeLater(...) or use a SwingWorker so background I/O stays off the EDT while UI updates run on it. (docs.oracle.com)

A practical, robust listener pattern avoids infinite blocking and supports clean shutdowns — use setSoTimeout(...) or close the socket from another thread, and always respect the packet’s actual length when converting bytes to a String. Example pattern (keeps loop in a background thread, posts UI updates to EDT, and uses getLength() to avoid trailing zeros):

volatile boolean running = true;
socket.setSoTimeout(1000); // milliseconds

Thread listener = new Thread(() -> {
  byte[] buf = new byte[MAXDATA];
  DatagramPacket pkt = new DatagramPacket(buf, buf.length);
  while (running) {
    try {
      socket.receive(pkt);
      String msg = new String(pkt.getData(), 0, pkt.getLength(), StandardCharsets.UTF_8);
      SwingUtilities.invokeLater(() -> txtRecieved.append("From " + pkt.getAddress() + ": " + msg + "\n"));
    } catch (SocketTimeoutException ste) {
      // timeout: loop back and check running flag
    } catch (IOException ioe) {
      // socket closed or fatal I/O — break and cleanup
      break;
    }
  }
});
listener.setDaemon(true);
listener.start();

setSoTimeout makes receive() time out with a SocketTimeoutException, which lets the loop check a shutdown flag; close() on the socket will make a blocked receive() throw a SocketException (useful for stopping the listener). Also prefer new String(pkt.getData(), 0, pkt.getLength(), ...) so only the received bytes are used. (docs.oracle.com)

About the “can’t send to myself” testing issue: UDP is connectionless and loopback/delivery semantics vary by setup. For reliable tests, run a separate sender socket (or a separate process) targeting the receiver’s bound port (127.0.0.1 is handy), and avoid swallowing exceptions — log them so socket/port/encoding problems become visible.

I answered my own question.. Ever hear of muti-threading and sub-classing?? well I did that lol, and learned something new.. Here's basically how I have it set up now:

This sub-class is within my main class:

public class Listener extends Thread {
    	public Listener() {
    		// NOTHING
    	}
    	public void run () {
	    	// Recieve data
			while (true) {
				byte[] rcvm = new byte[MAXDATA];
				DatagramPacket NewPacket = new DatagramPacket(rcvm, rcvm.length);
				try {
					DGS.receive(NewPacket);
				} catch (Exception ex) {
					// IGNORE
				}
				if (!(NewPacket.getAddress() == null))
				txtRecieved.append("Message from " + NewPacket.getAddress()
					+ ": " + new String(NewPacket.getData()) + "\n");
			}
    	}
    }

I call it using new Listener().start(); and it runs in the background not disturbing my app at all! YAY!! Now to find someone to test it with to make sure it works fine.. Unfortunately I can't send a message to myself and if I do nothing happens, I guess because I'm using Datagram t never gets back to me becasue my socket is currently busy sending the data.. so..

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.