I wrote a simple server client program today, but I have a problem and don't know why.
Here are my 3 important classes(all methods are called properly):
public class Server {
private ServerSocket server;
private ArrayList<Client> clients = new ArrayList<Client>();
public Server(int port) {
try {
server = new ServerSocket(port);
server.setSoTimeout(900000);
} catch (IOException e) {
e.printStackTrace();
}
acceptClients();
Main.frame.log("Server started on port "+port);
}
public void acceptClients() {
Thread t = new Thread() {
#Override
public void run() {
System.out.println("Accepting");
while(true) {
try {
Socket client = server.accept();
System.out.println("Accepted: "+client.getLocalSocketAddress());
clients.add(new Client(client));
} catch (IOException e) {
e.printStackTrace();
break;
}
}
};
};
t.start();
}
}
public class Client {
private static Socket client;
private static DataOutputStream out;
private static DataInputStream in;
public static void main(String[] args) throws UnknownHostException, IOException {
client = new Socket("localhost", 1567);
client.setSoTimeout(900000);
in = new DataInputStream(client.getInputStream());
out = new DataOutputStream(client.getOutputStream());
receive();
send("Hi I am a client!");
}
public static void receive() {
Thread t = new Thread() {
#Override
public void run() {
while (true) {
try {
String data = in.readUTF();
System.out.println("Received: "+data);
send("Test");
} catch (IOException e) {
e.printStackTrace();
break;
}
}
};
};
t.start();
}
public static void send(String data) {
try {
System.out.println("Sending");
out.writeUTF(data);
System.out.println("Sent: "+data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
The client handler of my server:
public class Client {
Socket socket;
DataOutputStream out;
DataInputStream in;
public Client(Socket client) {
socket = client;
try {
socket.setSoTimeout(900000);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
receive();
} catch (IOException e) {
e.printStackTrace();
}
}
private void receive() {
Thread t = new Thread() {
#Override
public void run() {
while (true) {
try {
process(in.readUTF());
in.close();
sleep(100);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
break;
}
}
}
};
t.start();
}
public void send(String data) {
try {
out.writeUTF(data);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void process(String data) {
Main.frame.log("Received--> "+data);
send("I received your message!");
}
}
When I execute the server and the client everything is fine until the client sends the second message. Then I get this error from the server:
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at de.julian.factoryserver.net.Client$1.run(Client.java:33)
And this error from my client:
java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at ftc.Client$1.run(Client.java:28)
I hope someone can help me!
In class Server, in method send you seem to have closed the outputstream, dont close it, just flush it
public void send(String data) {
try {
out.writeUTF(data);
out.close(); // remove this and replace it with out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
also in recieve you seem to prematurely close the inputstream
private void receive() {
Thread t = new Thread() {
#Override
public void run() {
while (true) {
try {
process(in.readUTF());
in.close(); // remove this
sleep(100);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
break;
}
}
}
};
t.start();
}
Apply the above fixes and that should fix your exceptions.
Related
I am Trying to create a simple client-server application for global chat I am getting the following error when quitting the connection from client Side.
java.net.SocketException: Socket closed
at java.net.SocketInputStream.read(SocketInputStream.java:203)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:223)
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:337)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at ReadFromServer.run(ChatClient.java:25)
and when client crashes without using Quit this error
java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:340)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at Clients.run(ChatServer.java:34)
ChatServer.java
import java.util.*;
import java.io.*;
import java.net.*;
class Clients extends Thread
{
private static ArrayList<DataOutputStream> clientOutputStreams;
private DataInputStream dataInputStream;
private DataOutputStream dataOutputStream;
private Socket socket;
static
{
clientOutputStreams=new ArrayList<>();
}
Clients(Socket socket)
{
try
{
this.socket=socket;
this.dataInputStream=new DataInputStream(socket.getInputStream());
this.dataOutputStream=new DataOutputStream(socket.getOutputStream());
clientOutputStreams.add(dataOutputStream);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void run()
{
try
{
try
{
String message=dataInputStream.readUTF();
while(!message.equalsIgnoreCase("quit"))
{
for(DataOutputStream dis:clientOutputStreams)
{
dis.writeUTF(message);
}
message=dataInputStream.readUTF();
}
Thread.currentThread().interrupt();
}
finally
{
dataInputStream.close();
dataOutputStream.close();
clientOutputStreams.remove(clientOutputStreams.indexOf(dataOutputStream));
socket.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public class ChatServer
{
public static void main(String[] args)throws Exception
{
try
{
ServerSocket serverSocket=new ServerSocket(9000);
while(true)
{
Socket s=serverSocket.accept();
Clients client=new Clients(s);
client.start();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
ChatClient.java
import java.util.*;
import java.io.*;
import java.net.*;
class ReadFromServer extends Thread
{
private DataInputStream readMessage;
ReadFromServer(Socket socket)
{
try
{
this.readMessage=new DataInputStream(socket.getInputStream());
}
catch(Exception e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
public void run()
{
try
{
while(!Thread.currentThread().isInterrupted())
{
System.out.println(readMessage.readUTF());
}
readMessage.close();
Thread.currentThread().interrupt();
if(Thread.currentThread().isInterrupted())
return;
}
catch(Exception e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
class WriteToServer extends Thread
{
private DataOutputStream writeMessage;
private String clientName;
private Socket socket;
WriteToServer(Socket socket,String clientName)
{
try
{
this.socket=socket;
this.writeMessage=new DataOutputStream(socket.getOutputStream());
this.clientName=clientName;
}
catch(Exception e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
public void run()
{
try
{
Scanner scanner=new Scanner(System.in);
String message=scanner.nextLine();
while(!message.equalsIgnoreCase("quit"))
{
writeMessage.writeUTF(clientName+":"+message);
message=scanner.nextLine();
}
writeMessage.writeUTF(message);
writeMessage.close();
Thread.currentThread().interrupt();
if(Thread.currentThread().isInterrupted())
return;
}
catch(Exception e)
{
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
public class ChatClient
{
public static void main(String[] args)
{
try
{
Socket socket=new Socket("localhost",9000);
try
{
System.out.print("Enter Your Name:");
Scanner scanner=new Scanner(System.in);
String clientName=scanner.nextLine();
ReadFromServer rfs=new ReadFromServer(socket);
WriteToServer wts=new WriteToServer(socket,clientName);
wts.start();
rfs.start();
while(wts.isAlive());
rfs.interrupt();
System.out.println("End of Both Threads");
//socket.close();
}
finally
{
socket.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
How to handle such situations when Socket is closed when being used by InputStreamReader
SocketClosedException means that you closed the socket, at writeMessage.close(), and then continued to use it, at readMessage.readUTF(). It's a bug in your code. You will have to sort out which of the reader and writer threads should do the closing, and it should only be one of them, and not while the other is still running.
The EOFException is exactly what you should expect when you call readUTF() on a connection that has already been closed by the peer. Catch it and handle it separately.
I wrote simple client serwer, but unfortunately, I did it so chaotic and poorly that I decided to write everything from scratch. I want to write to communicate in both directions with the ability to disconnect and connect a new client. It means the client or the server sends a message and an appropriate one reads it. At the beginning all works but when i want to close client i get two errors:
java.net.SocketException: Socket closed readSocketData()
java.net.SocketException: Socket closedwriteData(String data)
Of course I understand what those errors means , but I do not understand why they show up because i have a while loop in which i check if the client is connected. Later when i try to connect a new client everything is falling apart.
I wrote 3 classes client, server and communication. Client and server inherits from communication (methods for opening and reading data streams). It all looks like that:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends Communication{
ServerSocket serverSocket;
Socket listener;
boolean listenerLife;
public Server(int port) {
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
System.out.println(e);
}
}
public void startListener(){
while (true){
try {
listener = serverSocket.accept();
listenerLife = true;
} catch (IOException e) {
System.out.println(e);
}
openWriter(listener);
openReader(listener);
writeServerDataThread();
new Thread(new Runnable() {
#Override
public void run() {
readData();
}
}).start();
}
}
public void writeServerDataThread(){
openLocalReader();
new Thread(new Runnable() {
#Override
public void run() {
while (true){
String data = readLocalData();
writeData(data);
}
}
}).start();
}
public void readData(){
while (listenerLife){
String data = readSocketData();
if("exit".equals(data) || data == null){
try {
listenerLife = false;
listener.close();
} catch (IOException e) {
System.out.println(e);
}
}
else {
System.out.println(data);
}
}
}
public void writeData(String data){
try {
writer.writeBytes(data + '\n');
writer.flush();
} catch (IOException e) {
System.out.println(e);
}
}
public static void main(String[] args) {
Server server = new Server(8080);
server.startListener();
}
}
import java.io.IOException;
import java.net.Socket;
public class Client extends Communication{
Socket clientSocket;
boolean clientLive;
public Client(String hostName, int port) {
try {
clientSocket = new Socket(hostName, port);
clientLive = true;
} catch (IOException e) {
System.out.println(e + "Client(String hostName, int port)");
}
}
public boolean closeConnection(String data){
if("exit".equals(data) || data == null){
try {
writeData("Zamykam klienta");
clientSocket.close();
clientLive = false;
return false;
} catch (IOException e) {
System.out.println(e + "closeConnection(String data)");
}
}
return true;
}
public void readClientData(){
new Thread(new Runnable() {
#Override
public synchronized void run() {
openLocalReader();
while (!clientSocket.isClosed()){
String data = readLocalData();
if(closeConnection(data)){
writeData(data);
}
}
}
}).start();
}
public void readServerDataThread(){
new Thread(new Runnable() {
#Override
public synchronized void run() {
while (!clientSocket.isClosed()){
String data = readSocketData();
if(closeConnection(data)){
System.out.println(data);
}
}
}
}).start();
}
public void writeData(String data){
try {
writer.writeBytes(data + '\n');
writer.flush();
} catch (IOException e) {
System.out.println(e + "writeData(String data)");
}
}
public static void main(String[] args) {
final Client client = new Client("localhost", 8080);
client.openReader(client.clientSocket);
client.openWriter(client.clientSocket);
client.readServerDataThread();
client.readClientData();
}
}
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class Communication {
BufferedReader reader;
BufferedReader localReader;
DataOutputStream writer;
public void openReader(Socket incomingSocket){
try {
reader = new BufferedReader(new InputStreamReader(incomingSocket.getInputStream()));
} catch (IOException e) {
System.out.println(e);
}
}
public void openWriter(Socket incomingSocket){
try {
writer = new DataOutputStream(incomingSocket.getOutputStream());
} catch (IOException e) {
System.out.println(e);
}
}
public void openLocalReader(){
localReader = new BufferedReader(new InputStreamReader(System.in));
}
public String readLocalData(){
String data = null;
try {
data = localReader.readLine();
} catch (IOException e) {
System.out.println(e + " readLocalData()");
}
return data;
}
public String readSocketData(){
String data = null;
try {
data = reader.readLine();
} catch (IOException e) {
System.out.println(e + " readSocketData()");
}
return data;
}
}
java.net.SocketException: Socket closed readSocketData()
java.net.SocketException: Socket closed writeData(String data)
Of course I understand what those errors means
They mean you closed the socket and continued to use it.
but I do not understand why they show up because i have a while loop in which i check if the client is connected.
No you don't. You have a while loop in which you check if the client socket is still open, which isn't the same thing at all ... but in any case that doesn't prevent you from using a closed socket inside the loop, for example after you close it in closeConnection(), whose return value being back to front from what it should be is doubtless causing confusion, and which is called by two threads as far as I can tell.
I am creating a client and server setup in order to send then server a command and then receive a reply. However when I run it the client throws and EOFException. I understand this is an end of file exception but I am not sure what I am doing wrong, or how I can fix it.
Code for Server:
public class Server {
private ServerSocket server;
private Socket connection;
private ObjectOutputStream output;
private ObjectInputStream input;
//SET UP AND RUN SERVER
public void startRunning() {
try {
server = new ServerSocket(6789, 100);
while (true) {
try {
waitForConnection();
setupStreams();
whileRunning();
} catch (Exception e) {
} finally {
closeAll();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//DURING RUN
private void whileRunning() throws IOException {
String message = "You are now connected";
sendMessage(message);
System.out.println("Connected to client");
}
//WAIT FOR CONNECTION THEN DISPLAYS INFO
private void waitForConnection() throws IOException {
System.out.println("Waiting for connection.....");
connection = server.accept();
System.out.println("Now connected to " + connection.getInetAddress().getHostAddress());
}
//SETS UP STREAMS
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
}
//SEND MESSAGE TO CLIENT
private void sendMessage(String message) {
try {
output.writeObject("SERVER - " + message);
output.flush();
System.out.println("SERVER - " + message);
}
catch (Exception e) {
System.out.println("ERROR: Can't send message");
}
}
//CLOSE STREAMS AND SOCKETS
private void closeAll() {
System.out.println("Closing Connections");
try {
output.close();
input.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Code for starting the server:
public class RunServer {
public static void main(String[] args) {
Server server = new Server();
server.startRunning();
}
}
Code for client:
public class Client {
private ObjectOutputStream output;
private ObjectInputStream input;
private String message = "";
private String serverIP;
private Socket connection;
public Client(String host) {
serverIP = host;
}
public void startRunning() {
try {
connectToServer();
setupStreams();
whileRunning();
}
catch (Exception e) {
} finally {
closeAll();
}
}
// CONNECT TO SERVER
public void connectToServer() throws IOException {
System.out.println("Attempted connection...");
connection = new Socket(InetAddress.getByName(serverIP), 6789);
System.out.println("Connected to: " + connection.getInetAddress().getHostName());
}
// SET UP STREAMS
private void setupStreams() throws IOException { output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
System.out.println("\nStreams Connected");
}
// WHILE CHATTING
private void whileRunning() throws IOException {
do {
try {
message = (String) input.readObject();
System.out.println(message);
} catch (Exception e) {
e.printStackTrace(); //In to view exception
System.out.println("Unable to get message");
System.exit(0); //In to stop it looping forever (Known issue)
}
} while (!message.equals("SERVER - END"));
}
// CLOSE STREAMS AND SOCKETS
public void closeAll() {
System.out.println("Closing sockets, closing streams");
try {
output.close();
input.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Code for starting the client:
public class RunClient {
public static void main(String[] args) {
Client client = new Client("localhost");
client.startRunning();
}
}
When I run the client it constantly loops saying "Unable to get message" forever.
However when I view the exception and exit the code (as added in) I get this problem:
Attempted connection...
Connected to: localhost
Streams Connected
SERVER - You are now connected
java.io.EOFException
Unable to get message
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at main.Client.whileRunning(Client.java:53)
at main.Client.startRunning(Client.java:26)
at main.RunClient.main(RunClient.java:7)
Any help or suggestions would be much appreciated. Thanks :)
EOFException is thrown when you get to the end of the stream, which happens when the peer closes the connection.
You need to catch it separately and not treat it as an error.
I also suggest you change System.exit(0); to break;.
This question already has answers here:
Official reasons for "Software caused connection abort: socket write error"
(14 answers)
Closed 9 years ago.
There are two computers, A and B, each one of them is waiting for the other one to tell him that is ready, when they receive the message they'll start doing something.
public class SyncClientImpl implements SyncClient, Runnable {
private Socket s;
private String ipAddress;
private int port;
private boolean otherIsReady;
private Thread thread;
private OutputStream os;
private ObjectOutputStream oos;
public Thread getThread() {
return thread;
}
public void setThread(Thread thread) {
this.thread = thread;
}
public void start() {
thread = new Thread(this);
thread.start();
}
public boolean isOtherIsReady() {
return otherIsReady;
}
public void setOtherIsReady(boolean otherIsReady) {
this.otherIsReady = otherIsReady;
}
public Socket getS() {
if (s == null) {
try {
s = new Socket(ipAddress, port);
} catch (UnknownHostException ex) {
Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
return s;
}
public void setS(Socket s) {
this.s = s;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
#Override
public void send(Object o, int port, String ipAdrress) {
try {
os = this.getS().getOutputStream();
oos = new ObjectOutputStream(os);
oos.flush();
oos.writeObject(o);
oos.flush();
} catch (IOException ex) {
Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void update() {
otherIsReady = true;
}
#Override
public void run() {
try {
while (!otherIsReady) {
try {
this.send("ready", port, ipAddress);
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
oos.close();
os.close();
s.close();
} catch (IOException ex) {
Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This first class sends the message "ready" to a server, it will stop doing it until someone else notify it.
The class that will notify it is this one:
public class SyncServerImpl implements SyncServer, Runnable {
private ServerSocket ss;
private Socket s;
private String ipAddress;
private int port;
private InputStream is;
private ObjectInputStream ois;
private boolean confirmReceived;
private Thread thread;
private transient List<Observer> list = new ArrayList<Observer>();
private Object lock;
public boolean isConfirmReceived() {
return confirmReceived;
}
public void setConfirmReceived(boolean confirmReceived) {
this.confirmReceived = confirmReceived;
}
#Override
public void setLock(Object lock) {
this.lock = lock;
}
public void start() {
thread = new Thread(this);
thread.start();
}
public Socket getS() {
if (s == null) {
try {
s = this.getSS().accept();
} catch (UnknownHostException ex) {
Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
return s;
}
public void setS(Socket s) {
this.s = s;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public ServerSocket getSS() {
if (ss == null) {
try {
ss = new ServerSocket(port);
} catch (IOException ex) {
Logger.getLogger(SyncServerImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
return ss;
}
public void setSS(ServerSocket ss) {
this.ss = ss;
}
#Override
public void addObserver(Observer observer) {
list.add(observer);
}
#Override
public void removeObserver(Observer observer) {
list.remove(observer);
}
#Override
public void notifyObservers() {
for (Observer observer : list) {
observer.update();
}
}
public void receive() {
try {
is = this.getS().getInputStream();
ois = new ObjectInputStream(is);
String to = (String) ois.readObject();
if (to.equalsIgnoreCase("ready")) {
synchronized (lock) {
confirmReceived = true;
this.notifyObservers();
lock.notifyAll();
}
System.out.println("packet received");
}
} catch (IOException ex) {
Logger.getLogger(SyncServerImpl.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(SyncServerImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void run() {
try {
while (!confirmReceived) {
this.receive();
}
ois.close();
is.close();
s.close();
ss.close();
} catch (Exception ex) {
Logger.getLogger(SyncServerImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]) {
final Object lock = new Object();
SyncServerImpl ss = new SyncServerImpl();
SyncClientImpl sc = new SyncClientImpl();
ss.setLock(lock);
ss.addObserver(sc);
ss.setPort(2002);
ss.start();
sc.setIpAddress("192.168.1.101");
sc.setPort(2002);
sc.start();
synchronized (lock) {
while (!ss.isConfirmReceived()) {
try {
lock.wait();
} catch (InterruptedException ex) {
}
}
}
System.out.println("Ok");
}
}
This Server is waiting for the message "ready" to arrive, when it comes it will notify the other class which will stop sending packets, and will notify the main thread waiting on the lock.
It works fine on the localhost but not on my LAN.
I have a mac and a pc, if I start the main method first from the pc and then from the mac, I get this error (from the mac, which will iterate endlessly).
sync.SyncClientImpl send
GRAVE: null
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1864)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1773)
at java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:229)
at tetris.logic.online.sync.SyncClientImpl.send(SyncClientImpl.java:87)
at tetris.logic.online.sync.SyncClientImpl.run(SyncClientImpl.java:106)
at java.lang.Thread.run(Thread.java:695)
while of the pc it reports me that the connection is refused (but it's ok because it starts first)
If I start first on the mac and the on the pc, I get this error (from the pc) which will iterate endlessly too:
sync.SyncClientImpl send
GRAVE: null
java.net.SocketException: Software caused connection abort: socket write error
...
at tetris.logic.online.sync.SyncClientImpl.send(SyncClientImpl.java:87)
at tetris.logic.online.sync.SyncClientImpl.run(SyncClientImpl.java:106)
at java.lang.Thread.run(Thread.java:695)
This error looks like to be the same of one above but described in a different manner.
Does any one knows what is causing this error?
Try to simplify your solution, and take a look at the following article on socket programming: Writing the Server Side of a Socket.
Try to make it work one way first before attempting to do it in both directions (although the need for that feature isn't quite clear to me). Right now the client & server threads within the same applications are interfering with the client/server pair you're trying to set up over the network.
If you only want to send text over the socket just use BufferedReader and PrintWriter instead of ObjectStreams (latter could get you into memory issues if not managed properly).
#Override
public void send(String line, int port, String ipAdrress) {
try {
Socket clientSocket = new Socket(ipAddress, port);
os = clientSocket.getOutputStream();
PrintWriter out= new PrintWriter(os, true);
out.println(line);
out.close();
clientSocket.close();
} catch (IOException ex) {
Logger.getLogger(SyncClientImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
If you only want to use the connection for checking if the other is ready than closing the Socket is ok, but if you'd want to keep the connection open you need to keep the OutputStream (not the Socket itself) for further processing in the Thread. Again, take a look at the article above and work from there.
I'm creating this little client-server program to learn about sockets, and so far, I'm having a bit of trouble. For the purpose of this post, I consolidated the code into a single class. And the code will compile. (So it will show the same errors I get)
When the client connects to the server, the server socket properly creates a socket on the server-side. The Client then successfully sends a message to the server, but when the server tries to send a response to the client, there is an error saying the socket is closed.
Main.java
package main;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Hashtable;
public class Main {
boolean running = true;
public static void main(String[] args){
new Main().start();
}
public void start(){
new Thread(new ConnectionListener()).start(); //Starts Server
try {
connectToServer();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public class ConnectionListener implements Runnable{
public void run() {
ServerSocket ss = null;
try {
ss = new ServerSocket(31415);
}catch (BindException e) {
e.printStackTrace();
return;
} catch (IOException e) {
e.printStackTrace();
return;
}
while(running){
try {
Socket sock = ss.accept();
ServerConnection c = new ServerConnection(sock);
c.start();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void connectToServer() throws UnknownHostException, IOException{
//Create Connection to Server
Socket socket = new Socket("localhost",31415);
ClientConnection cc = new ClientConnection(socket);
cc.start();
//Send First Message to Server
Hashtable<Integer, String> htt = new Hashtable<Integer, String>();
htt.put(0,"Hello, This is a Chat Test");
Message m = new Message(Message.Type.CHAT,htt);
cc.sendMessage(m);
}
public class ServerConnection{
Socket sock;
boolean connected = true;
public ServerConnection(Socket sock){
this.sock = sock;
}
public void start() {
new Thread(new RequestListener()).start();
}
private void handleMessage(Message m){
System.out.println("Server : Handle message " + m.type.toString());
}
public void disconnect(){
System.out.println("Disconnect user");
}
public void sendMessage(Message m){
try {
ObjectOutputStream os = new ObjectOutputStream(sock.getOutputStream());
os.writeObject(m);
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class RequestListener implements Runnable{
public void run() {
ObjectInputStream is = null;
try {
is = new ObjectInputStream(sock.getInputStream());
while(connected){
try {
Message m = (Message)
is.readObject(); //EOFException
handleMessage(m);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch(SocketException e){
disconnect();
e.printStackTrace();
break;
}catch (IOException e) {
//e.printStackTrace(); //EOFException Here
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class ClientConnection {
private Socket socket;
private boolean connected = true;
public ClientConnection(Socket socket) {
this.socket = socket;
}
public void start(){
new Thread(new RequestListener()).start();
}
public void sendMessage(Message m){
try {
ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
os.writeObject(m);
os.flush();
os.close();
} catch (IOException e) {
System.out.println("Error Sending Message");
e.printStackTrace();
}
}
public void close() throws IOException{
Message m = new Message(Message.Type.DISCONNECT,null);
sendMessage(m);
socket.close();
}
private void handleMessage(Message m){
System.out.println("Client : Handle message " + m.type.toString());
}
class RequestListener implements Runnable{
public void run() {
ObjectInputStream is = null;
try {
System.out.println(socket.isConnected()); //true
System.out.println(socket.isClosed()); //false
InputStream iss = socket.getInputStream();
is = new ObjectInputStream(iss); //socketClosedException
while(connected){
try {
Message m = (Message)is.readObject();
handleMessage(m);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch(SocketException e){
System.out.println("Server Disconnected");
break;
}catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
Message.java
package main;
import java.io.Serializable;
import java.util.Hashtable;
public class Message implements Serializable{
public enum Type{
LOGIN, PM, DISCONNECT, INCORRECT_LP,CORRECT_LP, UPDATE_USERLIST, CHAT, INCORRECT_VERSION
}
public Type type;
Hashtable ht;
public Message(Type type, Hashtable ht){
this.type = type;
this.ht = ht;
}
public Object get(Object o){
return ht.get(o);
}
}
There's nothing 'random' about it.
Closing the input or output stream of a Socket closes the other stream and the Socket.
In this case you are closing the ObjectOutputStream you have wrapped around the socket's output stream, which closes that output stream, which closes the socket's input stream and the socket.