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.
Related
Here's my client code:
public static void main(final String[] args)
{
try (final Scanner scanner = new Scanner(System.in))
{
System.out.println("Type:");
try (final Socket socket = new Socket("127.0.0.1", 80);
final DataOutputStream dout = new DataOutputStream(socket.getOutputStream()))
{
while (scanner.hasNext())
{
dout.writeUTF(scanner.nextLine());
dout.flush();
}
}
}
catch (final Exception e)
{
e.printStackTrace();
}
and here's my server:
public ConnectorData()
{
try
{
_server = new ServerSocket(80);
}
catch (final Exception e)
{
e.printStackTrace();
}
while (true)
{
try
{
try (final Socket socket = _server.accept();
final DataInputStream dis = new DataInputStream(socket.getInputStream()))
{
System.out.println(dis.readUTF());
}
}
catch (final Exception e)
{
e.printStackTrace();
}
}
}
it works fine in the first message but when i type again in console and hit enter it freezes and then i send again third time and it throw me an:
java SocketException: An established connection was aborted by the software in your host machine
What is it for? Where is my mistake? I basically want to type in chat anything i want and when i press enter to send in server and print it out on console.
Compare and contrast:
Your client creates a Socket connected to your server, then sends a bunch of Strings through it.
Your server accepts a connection from a client to establish a Socket, reads one String from it, and then goes back to repeat the whole process.
It is not surprising, then, that the first line you type at the client is transferred successfully, but subsequent ones are not. The server's behavior needs to match the client: it needs to keep reading data from the same socket until the client is done sending. If you want it to afterward loop back to try to accept another connection then that's a separate matter.
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 !
I have many clients that are waiting for server messages. So the client make accept() and wait for server. When server have messages, open a connection to the client and send messages, after that, close the communication and the cycle restart.
I've seen usually the inverse approach, where the server do accept() and client connect to it. I've wrote this code but the client (that do accept() ) is blocked on point 3 and the server (that create the connection to the client) is blocked on point 2.
Sure i have some problems in my code (dont know where), but... this is the correct way ?
The client (that do accept() and wait for new messages)
try {
System.out.println("Waiting..");
receiver = serverSocket.accept();
System.out.println("1");
ObjectInput fromServerReader = new ObjectInputStream(receiver.getInputStream());
ObjectOutputStream toServerWriter = new ObjectOutputStream(receiver.getOutputStream());
System.out.println("2");
toServerWriter.writeObject("dummy");
toServerWriter.flush();
System.out.println("3");
ScheduledEvent scheduledEvent = (ScheduledEvent) fromServerReader.readObject();
System.out.println("4");
receiver.close();
System.out.println("5");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
// Should never happen
}
The server (that when have new message to send to client, create the
connection)
try {
InetAddress address = InetAddress.getByName(sendToUser
.getMachineName());
socket = new Socket(address, port);
log.debug("1");
ObjectOutputStream toClientWriter = new ObjectOutputStream(
socket.getOutputStream());
ObjectInputStream fromClientReader = new ObjectInputStream(socket.getInputStream());
log.debug("2");
String read = (String)fromClientReader.readObject();
log.debug("3");
// Compose the message
ScheduledEvent scheduledEvent = new ScheduledEvent();
scheduledEvent.setSubject(event.getSubject());
scheduledEvent.setMessage(event.getText());
log.debug("4");
toClientWriter.writeObject(scheduledEvent);
toClientWriter.flush();
log.debug("5");
socket.close();
log.debug("6");
} catch (UnknownHostException e) {
// TODO handle
e.printStackTrace();
} catch (IOException | ClassNotFoundException e) {
// TODO handle
e.printStackTrace();
}
In client code, instead of using
PrintWriter writer;
Use
ObjectOutputStream writer;
And then use
writer.writeObject("dummy");
writer.flush();
Try using println instead of write toServerWriter.println("dummy");. The server may be waiting for the newline character.
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 need to build an app where I have four servers running and one client send some packages to these servers, but these servers have to keep running all the time receiving something from the client(sender).
So I create the both classes, client and server:
public class Server {
public Event receive(int port) {
Evento event = null;
try {
ServerSocket ss = new ServerSocket(port);
Socket s = ss.accept();
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
evento = (Evento) ois.readObject();
is.close();
s.close();
ss.close();
}catch(Exception e){
System.out.println(e);
}
return event;
}
}
public class Client {
public void send(Event event, int port) {
try {
Socket s = new Socket("localhost", 2002);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(event);
oos.close();
os.close();
s.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
But as I said, I need these servers keep running all the time, if I test once, that's ok, but twice or more, don't.
How could I do that ?
The standard pattern is to create one thread for each connection. If you use one thread you can only read from one blocking connection.
just add a do while block around the readObject.
As a break condition you can check whether the message is something like "exit"..
cheers