UDP broadcast client in Java - java

I am using UDP broadcast for interservice communication The server is in Python and I can see the UDP messages using this code:
import sys
import socket
HOST = ''
PORT = 9002
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
s.bind((HOST,PORT))
while True:
try:
message = s.recv(8192)
print("Got data: " + message)
except KeyboardInterrupt:
sys.exit()
I can run as many of these clients simultaneously as I want on the same machine.
I'm trying to implement a similar client in Java using the DatagramSocket class, but I keep getting an "address already in use" error. Evidently I need to construct it differently than I am currently:
DatagramSocket socket = new DatagramSocket(broadcastPort);
Is it possible to get the same behavior as the Python code?

Try this:
// create an unbound socket
DatagramSocket socket = new DatagramSocket(null);
// make it possible to bind several sockets to the same port
socket.setReuseAddress(true);
// might not be necessary, but for clarity
socket.setBroadcast(true);
socket.bind(new InetSocketAddress(9002));
The null argument to the constructor is the key here. That wisdom is hidden in the second paragraph of the javadoc for the DatagramSocket(SocketAddress bindAddress) constructor:
if the address is null, creates an unbound socket.

Address already in use probably means you haven't properly terminated your programs. If you're using Eclipse, make sure you check all your open consoles and terminate all of them. (Top right corner, blue box - click it and it'll show all running programs)
In Eclipse, just because you "run" your program again, it doesn't terminate the previous one(s).
Another possible issue is that you may be using the same port as your python server. 2 Applications can't claim the same port, so just change the port number if that is the case.
Edit: Use a MulticastSocket.

Related

Why and how am i supposed to use socket.accept() in python?

This accept() method return a tuple with a new socket and an address but why do i need a new socket if i already have one, so why don't use it?
import socket
sock = socket.socket()
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()
print 'connected:', addr
while True:
data = conn.recv(1024)
if not data:
break
conn.send(data.upper())
conn.close()
ps: When i program sockets in Java, i don't really have this kind of accepting stuff and i only need one socket per client and one per server, which makes sense.
You have one listening socket active while the server is running and one new connected socket for each accepted connection which is active until the connection is closed.
Seems like you haven't implemented TCP in Java before.
The example you are providing with, uses a default AF_INET and SOCK_STREAM which by default is TCP:
socket.socket([family[, type[, proto]]])
Create a new socket using the given address family, socket type and protocol number. The address family should be AF_INET (the default), AF_INET6 or AF_UNIX. The socket type should be SOCK_STREAM (the default), SOCK_DGRAM or perhaps one of the other SOCK_ constants. The protocol number is usually zero and may be omitted in that case.
If you were implemented SOCK_DGRAM which is UDP, you wouldn't need to be using sock.accept()

Java.net.SocketException: Permission denied: connect

I have two PCs in one network that I want to connect. One of them should send a notification to the other via TCP. One the one PC I have a "server" (Python script) socket which waits for the "client"(Jar file) to send a specific String and then it gives me a notification. This works perfectly fine when I'm trying it out one one PC. But when I want to do the intended action the "client" PC's .jar gives me an error that the connection is refused. Do I have to open a specific port on the other PC or what else could cause trouble? One PC runs Fedora the other Windows 8
"Server Code"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 5005))
s.listen(1)
try:
while True:
komm, addr = s.accept()
while True:
data = komm.recv(1024)
if data == "$":
noty()
if not data:
komm.close()
break
finally:
s.close()
"Client" Code
public static void main(String[] args) throws Exception {
Socket socket = new Socket("192.168.178.25", 5005);
OutputStream out = socket.getOutputStream();
String dat = "$";
out.write(dat.getBytes());
socket.close();
}
Your server is probably binding to the wrong interface,
calling
s.bind(("", 5005))
Without setting an interface will allow the program to pick what ip address / interface it will connect to.
Since your client is trying to connect to ("192.168.178.25", 5005); you may want to put an IP address into the bind call to prevent the server picking the wrong ip interface.
Example:
s.bind(("192.168.178.25", 5005))
if its permission denied then something is blocking your connection with the computer. i would try to open a port and see if that works. if you want an example of java sockets you can take a look at my SUPER Tic-Tac-Toe Multiplayer it uses java sockets to send strings to the clients as a way to represent what actions the clients should take.

DatagramSocket Broadcast Behavior (Windows vs. Linux)

Backstory:
I have a wireless device which creates it's own SSID, assigns itself an IP address using auto-ip, and begins broadcasting discovery information to 255.255.255.255. (unfortunately, it does not easily support multicast)
What I'm trying to do:
I need to be able to receive the discovery information, then send configuration information to the device. The problem is, with auto-ip, the "IP negotiation" process can take minutes on Windows, etc (during which time I can see the broadcasts and can even send broadcast information back to the device).
So I enumerate all connected network interfaces (can't directly tell which will be used to talk to the device), create a DatagramSocket for each of their addresses, then start listening. If I receive the discovery information via a particular socket, I know I can use that same socket to send data back to the device. This works on Windows.
The problem:
On Linux and OSX, the following code does not receive broadcast packets:
byte[] addr = {(byte)169, (byte)254, (byte)6, (byte)215};
DatagramSocket foo = new DatagramSocket(new InetSocketAddress(InetAddress.getByAddress(addr), PORT_NUM));
while (true)
{
byte[] buf = new byte[256];
DatagramPacket pct = new DatagramPacket(buf, buf.length);
foo.receive(pct);
System.out.println( IoBuffer.wrap(buf).getHexDump() );
}
In order to receive broadcast packets (on Linux/OSX), I need to create my DatagramSocket using:
DatagramSocket foo = new DatagramSocket(PORT_NUM);
However, when I then use this socket to send data back to the device, the packet is routed by the OS (I'm assuming) and since the interface of interest may be in the middle of auto-ip negotiation, fails.
Thoughts on the following?
How to get the "working" Windows behavior to happen on Linux/OSX
A better way to handle this process
Thanks in advance!
I do not think this is the problem with the code. Have you checked if OSX/Linux has correctly allowed those address / port number through their firewalls? I had this simple problem too in the past =P..
FYI, there is a nice technology called Zero-configuration which was built to solve this problem. It is very easy to learn so I recommend you to having a look at that as well.
Good luck.

Receiving UDP data in Java

I'm trying to receive UDP data broadcast by PlayCap to network address 192.168.103.255 port 3000 in Java, but I'm having trouble setting things up. Here's what I have:
DatagramSocket socket = new DatagramSocket();
InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000);
socket.bind(address);
I'm getting "java.net.SocketException: already bound" from the bind call. I'm pretty inexperienced with networking, so I may be doing something way wrong here. Any help is appreciated.
Here is the stacktrace:
java.net.SocketException: already bound
at java.net.DatagramSocket.bind(Unknown Source)
at runner.main(runner.java:16)
I dont want to revive and old thread but i don't think the answer to this question is correct. I faced the same issue when i used the similar code to create a DatagramSocket.
DatagramSocket socket = new DatagramSocket();
socket.setReuseAddress(true);
socket.bind(new InetSocketAddress(InetAddress.getByName("localhost"), 5566));
This results in a SocketException
Exception in thread "main" java.net.SocketException: already bound
at java.net.DatagramSocket.bind(DatagramSocket.java:376)
at testapplication.TestApplication.main(TestApplication.java:25)
Java Result: 1
Not because there is another process occupying the same port but i have created an already BOUND datagram socket when i use the default constructor.
new DatagramSocket()
According to javadoc:
DatagramSocket()
Constructs a datagram socket and binds it to any available port on the
local host machine.
So the reason for the exception is you are trying to bind an already bound socket. To make it work you need to create an unbond socket with below constructor
DatagramSocket socket = new DatagramSocket(null);
InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000);
socket.bind(address);
Hope this helps...
Do netstat -a -o -n and from this you can find that either this port is already bind or not(even from this you can get all the bound ports).If yes , then try any other port :)
Most probably your application is running twice. Or you might be executing the same code twice. Even the same application may fail when binding twice.
Happens a lot for beginners that they didn't shut down their previous attempt (happened to me, too), and then their port is already in use. Make sure to add proper exception handling, e.g. by popping up a message "Port already in use."
Note that for listening you usually will bind a port only, without an explicit address (you might need to use "0.0.0.0" for this). Then you can receive both broadcast and unicast.
The code I use for listening to broadcasts is simply:
DatagramSocket s = new DatagramSocket();
s.bind(new InetSocketAddress(port))
Note that I'm not binding to a particular address, but only to a port.
Check the port 3000 it may be already used by another application. Try using a different port.

UDP port scanning Java finds only 1 open UDP port

I have an assigment about port scanning. I am scanning UDP ports of some IP addresses in Java.In my program (assuming everything is OK) I can only find one open UDP port. In the other hands port scanning over "nmap" I get 4 open UDP ports. Can somebody tell me why I can not find more than one ports via Java code?
By the way I can find the true open port in my code.
int startPortRange=1;
int stopPortRange=1024;
InetAddress address = InetAddress.getByName("bigblackbox.cs.binghamton.edu");
int counter=0;
for(int i=startPortRange; i <=stopPortRange; i++)
{
counter++;
try{
byte [] bytes = new byte[128];
DatagramSocket ds = new DatagramSocket();
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.setSoTimeout(100);
ds.connect(address, i);
ds.send(dp);
ds.isConnected();
dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);
ds.close();
System.out.println("open");
System.out.println(counter);
}
catch(InterruptedIOException e){
//System.out.println("closed");
}
catch(IOException e){
//System.out.println("closed");
}
}
Output of above code is
135 open
When I make same operation in command line using nmap I get more open ports.
I could not upload an image because I am a new user.
Thank you
It is impossible to provide a concrete answer, unless you provide at least:
The source code of your program.
An example of the (incorrect) output that you are getting.
The expected output for the same scenario.
Without this information there is no way for us to tell you what is wrong. For all we know, it could even be a simple case of your program terminating prematurely after finding an open port. Or a case of the open port that was last found overwriting the entries of the previous ones before being displayed.
In any case, it might be worthwhile to investigate what is being sent and received using a network sniffer, such as Wireshark. By comparing an nmap session with a session created by your program, you might be able to spot some significant difference that would help pinpoint the issue.
EDIT:
After having a look at your code and comparing with nmap, it seems that you are mistakenly handling the case of a SocketTimeoutException as a closed port, while it could simply be the port of a server that refuses to answer to the packet that you sent.
EDIT 2:
Here's the full story:
When a port is properly closed, the server sends back an ICMP Destination Unreachable packet with the Port unreachable error code. Java interprets this error to an IOException that you correctly consider to indicate a closed port.
An open port, on the other hand may result into two different responses from the server:
The server sends back a UDP packet, which is received by your program and definitely indicates an open port. DNS servers, for example, often respond with a Format error response. nmap shows these ports are open.
The server ignores your probe packet because it is malformed w.r.t. to the provided service. This results in a network timeout and a SocketTimeoutException in your program.
Unfortunately there is no way to tell whether a network timeout is because an active server ignored a malformed probe packet or because a packet filter cut down the probe. This is why nmap displays ports that time out as open|filtered.

Categories

Resources