I've made a java application which uses UDP and I can't seem to receive packets outside LAN when hosting on my computer. I tried putting my application on a Hosted Server and it seemed to work (receives packet).
What is causing this to happen? I want it to work on my computer as well.
CLIENT:
try {
this.socket = new DatagramSocket(2500);
} catch (SocketException e1) {
System.out.println("Could not establish connection");
return;
}
while(true){
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
try{
socket.receive(packet);
}catch(IOException e){
System.out.println("Connection close");
break;
}
System.out.println("RECEIVED " + new String(packet.getData()));
}
SERVER:
try {
this.socket = new DatagramSocket(25860);
} catch (SocketException e) {
e.printStackTrace();
}
try {
byte[] data = datas.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress, 2500);
socket.send(packet);
}catch(IOException e) {
}
System.out.println("Sent " + ipAddress.getHostAddress() + ":" + port + " " + new String(datas));
IP Address is correct, it exactly prints out the same IP as my CLIENT. However I'm still not receiving.
If it works in one computer (single) and not on the other try checking the firewall, UDP connections should be allowed in your computer.
Related
I've created program to send and get data from client to server and for client i used java and server I used Visual Basic so how to set the connection between client and server is keep alive in a client(java) side?
this is the code from client :
public static void Client(){
String print = "";
String dataDB = "Hello server, From Client";
try(Socket clientSocket = new Socket("localhost", port)){
clientSocket.getOutputStream().write(dataDB.getBytes("ASCII"));
while (clientSocket.getInputStream().available() == 0) {
Thread.sleep(100L);
}
byte[] data = new byte[clientSocket.getInputStream().available()];
int bytes = clientSocket.getInputStream().read(data, 0, data.length);
print = new String(data, 0, bytes, "ASCII");//.substring(4,bytes);
while(print.length()>0){
System.out.println("From Server : "+print);
}
}catch (IOException ex){
System.out.println("I/O error: " + ex.getMessage());
}catch(InterruptedException ie){
System.out.println("error: " + ie.getMessage());
}catch(Exception e){
System.out.println("error: " + e.getMessage());
}
}
The Java client is a console application, just sent and get data from server i tried to used clientSocket.setKeepAlive(true); but is not working.
I am trying to access UDP data from server on port 1050. I am not receiving data in emulator and phone too, Seems like there is no issue in code because i am not getting any error in catlog. Any help will be appreciated. Thank you.
try {
int port = 1050;
DatagramSocket dsocket = new DatagramSocket(1050);
dsocket.setReuseAddress(true);
dsocket.setBroadcast(true);
byte[] buffer = new byte[2048];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
dsocket.receive(packet);
String lText = new String(buffer, 0, packet.getLength());
Toast.makeText(getApplicationContext(),"Data is coming...."+lText,Toast.LENGTH_LONG).show();
Log.i("UDP packet received", lText);
packet.setLength(buffer.length);
}
}
catch (IOException e) {
System.err.println(e);
e.printStackTrace();
}
I am attempting to add a multiplayer form to a simple pong game, but when I try to start the DatagramPacket and try to read the IP and port it says the ip is null and the port is -1. Does anyone know why it would be doing this? I thought maybe it was because the socket hadn't recieved the packet yet, but when I look I saw that all code after socket.recieve(packet) isn't running.
Code where I start the server:
public GameServer(PongEngine engine) {
this.engine = engine;
try {
this.socket = new DatagramSocket(4269);
} catch (SocketException e) {
e.printStackTrace();
}
}
public void run() {
while(true) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
System.out.println(packet.getAddress() + ":" + packet.getPort());
try {
socket.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
String message = new String(packet.getData());
if(message.trim().equalsIgnoreCase("ping")) {
System.out.println("CLIENT[" + packet.getAddress() + ":" + packet.getPort() + "] > " + message);
sendData("pong".getBytes(), packet.getAddress(), packet.getPort());
}
}
}
DatagramPacket's getAddress returns the IP address of the machine to which this datagram is being sent or from which the datagram was received.
In the first System.out.println you have just created the object, but have not done any network I/O with it.
Then you ignore the exception and just try to work with the datagram. If there was an I/O error, it's likely that the datagram was not initialized and hence still has IP address null and port -1.
If nothing happens after socket.receive() I'd assume the call is blocked, waiting for a packet to come in. Do you actually run the client that connects to your server code?
To add to Roberts answer, your code is simply out of order. Once you have that fixed then you can address why you might not be recieving a packet form the other PC like ccarton suggested.
Try this, and note the two comments
public void run() {
while(true) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
try {
//Wait for packet (The code will not move on until a packet is received or there is an error)
System.out.println("Waiting for packet");
socket.receive(packet);
//Move your socket/port info after receiving a packet so you don't get null or -1
System.out.println("Packet received: "+ packet.getAddress() + ":" + packet.getPort());
//Move your code inside try, rather than after
String message = new String(packet.getData());
if(message.trim().equalsIgnoreCase("ping")) {
System.out.println("CLIENT[" + packet.getAddress() + ":" + packet.getPort() + "] > " + message);
sendData("pong".getBytes(), packet.getAddress(), packet.getPort());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Now do you still get the same issues?
So, as the title might have suggested I am having a bit of trouble in my Java project. What I want to do is this:
I have two Computers running application X
Also have another three Computers running application Y
What i need to do is to establish a connection between a X and an Y. For example, someone uses the computer running X, and after the discovrey process, they will be returned a list of computers running the Y app, and their IP, and the other way around.
I've done this using UDP broadcasting, but sometimes it fails. The computers are connected via WiFi, so basically through a router. On many occasions, any of the X computers can see the Y ones via my UDP discovery method, but sometimes not, unless I manually point the IP, sometimes not even then.
Here is a code for discovering servers listening on a specific port:
public static ArrayList<InetAddress> searchComputer() {
ArrayList<InetAddress> targets = new ArrayList<InetAddress>();
try {
c = new DatagramSocket();
c.setBroadcast(true);
byte[] sendData = "DISCOVER_PC_SERVER_REQUEST".getBytes();
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), 2005);
c.send(sendPacket);
} catch (Exception e) {}
Enumeration interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = (NetworkInterface) interfaces.nextElement();
if (networkInterface.isLoopback() || !networkInterface.isUp()) {
continue;
}
for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
InetAddress broadcast = interfaceAddress.getBroadcast();
if (broadcast == null) {
continue;
}
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, broadcast, 8888);
c.send(sendPacket);
} catch (Exception e) { }
}
}
byte[] recvBuf = new byte[15000];
DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
if (useInstant) {
c.setSoTimeout(500);
}
else {
c.setSoTimeout(4000); //EXECUTE THE WHILE FOR 4 SECONDS, THEN RETURN WHATEVER THE RESULTS ARE.
}
while (true) {
c.receive(receivePacket);
String message = new String(receivePacket.getData()).trim();
if (message.equals("DISCOVER_PC_SERVER_RESPONSE")) {
// return receivePacket.getAddress();
targets.add(receivePacket.getAddress());
}
}
// c.close();
} catch (IOException ex){}
return targets;
}
And here is my "server":
private void start_Discovery() throws Exception {
//Keep a socket open to listen to all the UDP trafic that is destined for this port
socket = new DatagramSocket(2005, InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);
while (true) {
// System.out.println(getClass().getName() + ">>>Ready to receive broadcast packets!");
//Receive a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
socket.receive(packet);
//Packet received
// System.out.println(getClass().getName() + ">>>Discovery packet received from: " + packet.getAddress().getHostAddress());
// System.out.println(getClass().getName() + ">>>Packet received; data: " + new String(packet.getData()));
//See if the packet holds the right command (message)
String message = new String(packet.getData()).trim();
if (message.equals("DISCOVER_ANDROID_SERVER_REQUEST")) {
byte[] sendData = "DISCOVER_ANDROID_SERVER_RESPONSE".getBytes();
//Send a response
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, packet.getAddress(), packet.getPort());
socket.send(sendPacket);
// System.out.println(getClass().getName() + ">>>Sent packet to: " + sendPacket.getAddress().getHostAddress());
}
}
}
Why sometimes they can't see each other, even if they are connected to the same router?
EXTRA: Is there a special case, the X computers are connected via LAN, and the Y ones via WiFi?
Why sometimes they can't see each other, even if they are connected to
the same router?
Because Broadcasting is done using UDP services which are connectionless protocols. With UDP you just send packets of data (datagrams) to some IP address on the network. You have no guarantee that the data will arrive.
Is there a special case, the X computers are connected via LAN, and
the Y ones via WiFi?
Even, the X cmputers are connected via LAN and the Y ones via WiFi, they all belong to the same network of router. Hence,network-discovery and network-services will be available. There won't be any problem with that. It's all fair and not different than the case which you're having!
I am triying to comunicate 2 machines through datagram sockets but I guess I am missing something...
Machine A is runs an Android App (client)
Machine B is a server writen in Python
I can send a message from A to B without any problem, but A never gets the answer from B, the code is the following:
Client (Java) :
InetAddress serverAddr = InetAddress.getByName("10.0.0.10");
DatagramSocket socket = new DatagramSocket();
byte[] bufSent = "register".getBytes();
DatagramPacket dpSent = new DatagramPacket(bufSent,bufSent.length, serverAddr, 8088);
socket.send(dpSent);
byte[] bufRecv = new byte[1024];
DatagramPacket dpReceive = new DatagramPacket(bufRecv, bufRecv.length);
socket.receive(dpReceive);
String serverMessage = new String(dpReceive.getData(), 0, dpReceive.getLength());
Log.v(LOGTAG, "Received " + serverMessage);
Server (Python):
import socket
UDP_IP_DEST = "10.0.0.11"
UDP_IP = "10.0.0.10"
UDP_PORT = 8088
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
if data:
print "received message:", data
sock.sendto("I got the message", (UDP_IP_DEST, UDP_PORT))
Does anyone see where is the mistake? The point is that I have tried to send the answer to another machine instead of the mobile and it works fine.
Thanks a lot.
I had a similar problem with receiving, here's some code we use in our app for Datagrams modified with your values, you can see we do a few things differently in the socket set up. mSocket is just a private DatagramSocket member variable. Give it a try. I think you might need to bind, and possible set the reuse address flag.
try
{
mSocket = new DatagramSocket(null);
mSocket.setReuseAddress(true);
mSocket.setBroadcast(false);
mSocket.bind(new InetSocketAddress(8088));
//Set a 1.5 second timeout for the coming receive calls
mSocket.setSoTimeout(1500);
String data = "myData";
DatagramPacket udpPacket = new DatagramPacket(data.getBytes(), data.length(), InetAddress.getByName("10.0.0.10"), 8088);
mSocket.send(udpPacket);
byte[] buf = new byte[1024];
DatagramPacket recvPacket = new DatagramPacket(buf, buf.length);
mSocket.receive(recvPacket);
String response = new String(recvPacket.getData());
}
catch (SocketException e)
{
e.printStackTrace();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}