I have an application that listens to a specific UDP port and receives data over it.
When I run it through eclipse I am able to receive the data, whether I receive it from an application that is running on the same machine (sends to localhost) or from a remote machine (using the same sending application).
However, when I generate an executable jar and trying to run it, it only runs when the sending application is on the same machine (sends to localhost).
Here is the code I use to listen to the incoming data:
public class listenToPort implements Runnable{
ByteArrayOutputStream mainBAOS = new ByteArrayOutputStream();
#Override
public void run() {
DatagramSocket Socket = null;
try {
Socket = new DatagramSocket(5000);
Socket.setSoTimeout(10000);
byte[] Input = new byte [571];
while(true) {
DatagramPacket Packet = new DatagramPacket(Input, Input.length);
Socket.receive(Packet);
byte[] data = new byte[Packet.getLength()];
System.arraycopy(Packet.getData(), 0, data, 0, Packet.getLength());
try {
synchronized (this){
mainBAOS.write(data);
}
} catch(IOException ex) {ex.printStackTrace();}
Thread.sleep(5);
}
}
catch (SocketTimeoutException ex) {System.out.println("No incoming data from socket, socket closed");}
catch(IOException ex) {ex.printStackTrace();}
catch (InterruptedException ex) {ex.printStackTrace();}
finally{
Socket.close();
}
}
}
What could be the reason for this odd behavior?
Any ideas on how to fix it?
Thank you for your help.
I should add that the programs do not throw any errors or anything like that, it just won't receive any data over the socket.
It is most probably a firewall issue. Most probably the firewall accepts connections on the given port only when the application is run using Eclipse.
Try deactivating it(if that is reasonable) to see whether it solves your problem or not !
Related
I have established a connection via sockets between two computers. I have created an own object called "Result" and I can successfully transfer it to the server computer from the client computer.
If I do this socket connection only on my computer then I can receive an object from the server computer as well.
The problem is when I try to receive an object from the server computer. I get error messages and I have the feeling that something is happening to my object that is being sent. If I open a saved (serializable) Result object on my own computer in notepad then I get a lot of random symbols but when I do the same on the server computer then it is only two symbols.
Here is my code, I'm using JFileChooser so I can easily access the object I want to send from the server, understandably I have access to both computers.
Code for the sending server
public static void serverSendObject() throws IOException, ClassNotFoundException {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(2001,10);
}
catch (IOException ex) {
System.out.println("Can't setup server on this port
number. ");
}
Socket socket = null;
OutputStream out = null;
ObjectOutputStream objOut = null;
try {
socket = serverSocket.accept();
}
catch (IOException ex) {
System.out.println("Can't accept client connection. ");
}
try {
out = socket.getOutputStream();
}
catch (IOException ex) {
System.out.println("Can't get socket input stream. ");
}
try {
objOut = new ObjectOutputStream(out);
}
catch (FileNotFoundException ex) {
System.out.println("File not found. ");
}
JFileChooser fc = new JFileChooser();
int reValue=fc.showOpenDialog(null);
if(reValue == JFileChooser.APPROVE_OPTION) {
try(ObjectInputStream objInput = new ObjectInputStream(new FileInputStream(fc.getSelectedFile()))) {
objOut.writeObject(objInput.readObject());
}
catch(IOException e) {
}
catch(ClassNotFoundException e) {
}
}
serverSocket.close();
socket.close();
}
Code for the receiving client
public void loadExternal() throws IOException, ClassNotFoundException {
Visualizer vis = new Visualizer();
currentVis=vis;
Socket socket = null;
String host= *insert IP address*
socket= new Socket(host, 2001);
InputStream in = socket.getInputStream();
ObjectInputStream objIn = new ObjectInputStream (in);
currentRes = (Result) objIn.readObject();
objIn.close();
socket.close();
}
I keep getting
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
as an error. I have tried to put a catch on this but it doesn't help. I have tried some different methods but nothing seems to work.
Just want to point out that the exact same code works when I connect the sockets on my OWN computer and that this problem occurs when I connect two different computers AND that I'm being able to send an object to the server computer.
EDIT: I think I can confirm that something has happaned to the object I have sent. A locally (via sockets) saved object is 1131 bytes while the object I have sent to the server computer is only 4 bytes.
I use the same kind of technique when I send the objects, with ObjectOutputStream at the client and ObjectInputStream at the server.
whenever you write anything. remember to flush and then close. Hope can help.
I'm programming a network software with Java, but I have a real problem using my application through a "true" network.
Let a software be a host, and listening for client connexions.
Here is my Server loop :
public void run() {
while (mServerSocket != null) {
try {
Socket wClient = mServerSocket.accept();
System.out.println("Client connecté");
wClient.setSoTimeout(50);
wClient.setTcpNoDelay(false);
Client c = new Client(wClient);
synchronized(this) {
mWaitingClients.add(c);
c.start();
}
} catch(Exception ex) {
System.out.println("Server error : " + ex.getMessage());
}
}
}
When a client tried to connect to the server, I use this function :
public Client connect(InetAddress addr, int port) throws Exception {
Socket socket = new Socket(addr, port);
socket.setSoTimeout(50);
socket.setTcpNoDelay(false);
Client c = new Client(socket);
c.start();
return c;
}
And here is the client loop :
public void run() {
try {
ObjectOutputStream out = new ObjectOutputStream(mSocket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(mSocket.getInputStream());
while(mSocket.isConnected() && !mSocket.isClosed()) {
for (int i = 0; i < mOutMessages.size(); i++) {
Message msg = mOutMessages.get(i);
out.writeObject(msg);
}
out.flush();
mOutMessages.clear();
Thread.sleep(50);
out.reset();
while(true) {
try {
Message m = (Message) in.readObject();
mInMessages.add(m);
} catch (Exception e) {
break;
}
}
Thread.sleep(50);
}
} catch(Exception ex) {
try {
mSocket.close();
} catch(Exception exx) {
exx.printStackTrace();
}
ex.printStackTrace();
}
}
Some other parts of the program do Message and put them in the Output list of the Client (mOutMessages).
Some other parts of the program read Message from the mInMessages of the Client.
But something is wrong with this. It works fine locally (server and client on the same computer), but fail or is hazardous (some messages are sent but never received) using two computers (with LAN or through the Internet).
Server ever detect connexions from the clients, send "handshake" messages to the client, but the client never receives them.
I'm more a C programmer than a Java one, and I never had this kind of problem using libc Sockets, so, why my way of doing is wrong ?
Thank you !
Edit :
My Server is created using this function :
public void open(int port) throws Exception {
mServerSocket = new ServerSocket(port);
start(); // Call the run mentionned above.
}
Edit :
Here is my solution, maybe it's not perfect but it works !
public void run() {
try {
BufferedOutputStream buf_out = new BufferedOutputStream(
mSocket.getOutputStream()
);
BufferedInputStream buf_in = new BufferedInputStream(
mSocket.getInputStream()
);
ObjectOutputStream out = new ObjectOutputStream(buf_out);
out.flush();
ObjectInputStream in = new ObjectInputStream(buf_in);
while(mSocket.isConnected() && !mSocket.isClosed()) {
for (int i = 0; i < mOutMessages.size(); i++) {
Message msg = mOutMessages.get(i);
out.writeObject(msg);
out.flush();
}
mOutMessages.clear();
out.reset();
while(true) {
try {
Message m = (Message) in.readObject();
mInMessages.add(m);
} catch (Exception e) {
break;
}
}
}
} catch(Exception ex) {
try {
mSocket.close();
} catch(Exception exx) {
exx.printStackTrace();
}
ex.printStackTrace();
}
If I understand right, both client and server use the run method. If both client and server happen to write sufficiently large messages (not fitting in involved buffers) at the same time then you get a deadlock because neither partner advances to reading (which would drain full buffers). Due to network delays, this might only happen in the non-local scenario, i.e. there may be enough time to pile up enough messages in the mOutMessages buffer.
Note that documentation of Socket.setSoTimeout (which you used) only says that it affects read()s. (For example, in my JDK, ObjectOutputStream seems to use a BlockDataOutputStream with a buffer size of 1024 bytes).
I recommend to either use a separate thread for reading/writing or (if you know the maximum messages size) use a sufficiently large buffer (by wrapping the SocketOutputStream in a BufferedOutputStream). If you opt for larger buffers, you may also want to write one message at a time (and try to read messages after each).
I have simple UDP server/client program, I forwarded my ports and server receives and sends packets via internet,but the client on the remote machine cant receive them,so im wondering how to receive packets without forwarding ports on client side(if its even possible)? And if its not possible , what should i do to make client to receive UDP packets via internet?
Client receive thread looks like this :
public void run(){
DatagramSocket serverSocket = null;
while(true){
try {
serverSocket = new DatagramSocket(7000+clientNumber+100);
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte[] receiveData = new byte[1024];
DatagramPacket receiveX = new DatagramPacket(receiveData, receiveData.length);
try {
serverSocket.receive(receiveX);
} catch (IOException e) {
System.out.println("Nepagavau paketo");
}
String korX = new String( receiveX.getData());
Play.priesoX = Float.parseFloat(korX);
serverSocket.close();
}
You don't need to do port forwarding for the client side, NAT takes care of that automatically.
http://en.wikipedia.org/wiki/Network_address_translation
Your client might not be reachable for different reasons (firewall, etc.).
So the end result of my program is an updating game client, but what i have so far is a server that is able to accept multiple connections, and a client that connects to the server. this is the code for the client portion:
public void client() {
Socket socket = null;
ObjectInputStream in = null;
ObjectOutputStream out = null;
try {
socket = new Socket(IP, Integer.parseInt(port));
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
do {
// have a conversation
try {
message = (String) in.readObject();
System.out.println("\n" + message);
} catch (Exception e) {
System.out.println("\n idk wtf that user sent!");
}
} while (!message.equals("CLIENT - END")); // When the user types "END"
System.err.println("CLOSED!!!");
System.exit(0);
}
and this is the code for the server portion:
public void run() {
// where everything happens
System.out.println("server- connected");
try {
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject("hi");
out.flush();
Thread.sleep(5000);
out.writeObject("close");
out.flush();
System.out.println("closed");
} catch (Exception e) {
e.printStackTrace();
}
}
now, i am running into this problem where, when my server sends the object "hi" the client appears to not receive it. i'm not totally sure if it does, but if it is getting it, it isnt printing it out like i wanted. i previously have made a chat program that does this same thing, and i pretty much copied it to this, but it isnt communicating. the most i get is the confirmation that they are connected. im not sure what is going on, but any help would be appreciated! thanks in advance!
create the ObjectOutputStreams before the ObjectInputStreams and flush them immediately after creation.
the constructor of an ObjectInputStream reads the stream header. this stream header is written by the constructor of the ObjectOutputStream (kind of an ugly implementation, but it is what it is). if you construct the OIS's first, they hang waiting for the header bytes.
I have a server in Java which listens for incoming connection to a specific port. And everything works as expected, my clients connect to the server and I'm able to send data between them.
My problem is that, when I shut down my client, turn it on again and try to reconnect, it won't connect (my server stays on all the time).
For me to reconnect, I have to restart my server again.
So I tried doing this on my server side:
InetSocketAddress serverAddr = new InetSocketAddress(serverIpAddress, serverPort);
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
//I tries setting up a reuse option
serverSocket.bind(serverAddr);
Even after setReuseAddress() my client won't connect unless I restart my server!
Has anyone any idea of how could that be done?
EDIT2:
try {
while(true){
clientSocket = serverSocket.accept();
System.out.println("S-a conectat clientul de monitorizare!");
os=new ObjectOutputStream(clientSocket.getOutputStream());
try{
coord=(Coordinate)queue.take();
System.out.println(coord.getLat()+coord.getLon()+coord.getVit()+coord.getwId()+coord.getime());
os.writeObject(coord);
os.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
}
} catch (IOException e) {
System.out.println(e);
try {
clientSocket.close();
os.close();
}catch(Exception e1) {
e1.printStackTrace();
}
}
New edit:
Thread pool server:
Main:
ThreadPooledServer server = new ThreadPooledServer(queue,7001);
new Thread(server).start();
ThreadPooledServer:
public class ThreadPooledServer implements Runnable {
protected ExecutorService threadPool =
Executors.newFixedThreadPool(5);
public void run() {
openServerSocket();
while (!isStopped()) {
Socket clientSocket = null;
try {
System.out.println("Serverul asteapta clienti spre conectare");
clientSocket = this.serverSocket.accept();
clientconnection++;
System.out.println("Serverul a acceptat clientul cu numarul:"
+ clientconnection);
} catch (IOException e) {
if (isStopped()) {
System.out.println("Server Stopped.");
return;
}
throw new RuntimeException("Error accepting client connection",
e);
}
WorkerRunnable workerRunnable = new WorkerRunnable(queue,clientSocket);
this.threadPool.execute(workerRunnable);
}
System.out.println("Server Stopped.");
}
public synchronized void stop() {
this.isStopped = true;
try {
this.threadPool.shutdown();
}
catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
private void openServerSocket() {
try {
InetSocketAddress serverAddr = new InetSocketAddress(SERVERIP,
serverPort);
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(serverAddr);
} catch (IOException e) {
throw new RuntimeException("Cannot open port", e);
}
}
this.serverSocket.close();
In your run method you accept one client and then go in to an endless loop, trying to write data to the ObjectOutputStream. When the client closes the connection an exception is thrown because you can no longer write to the stream. At this point we're out of the endless loop(while(true) { .. }) and the run method ends.
If you want to keep accepting clients I suggest you move the while loop to the top of your code, above the accept to be exact.
Pseudo-ish code below(note: I'm not catching any exceptions etc.):
while (true)
{
// Wait for a client to connect..
Socket clientSocket = serverSocket.accept();
// Write to the client..
ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream());
os.writeObject(coord);
os.flush();
}
Is your server single threaded for a purpose (do you only accept one client at a time) ? Usually, servers will spawn a separate thread for every connections, so it can listen more often for incoming connections, and so if the client's connection throws any errors, it won't affect the listening socket. At the moment, your server will listen to only one connection, and if an exception occurs handling the client's connection, simply move on and never listen again. In pseudocode, a typical server is like :
Server listening thread (main thread)
try {
create server socket and bind to port
while server is online
listen for incoming connections
if the client connection is accepted [1]
start client thread
catch exception
handle exception
finally
make sure the server socket is disconnected
cleanup
Server client connection thread
write to client socket to initialize connection
try
while scoket is opened
read data
data treatment
write response
catch exceptions
handle exception [2]
finally
close client socket
cleanup
[1] if your server handles only one client, it should refuse the connection, so the client doesn't wait for no reason
[2] if the exception is not about the socket, the client should be warned by a final write to the socket before closing it
Client thread (on the client's side)
try
connect to server
protocol handshake (optional) [4]
while socket is connected
client server communication
catch exception
handle excpetion
finally
close socket
[4] since the server should write to the socket first, the client should read from it for any welcome message or error messages before attempting to write anything.