If i start the Server first and then the Client everything works perfect, but when i start the client first and then the server(making sure that the Client is able to connect when the svr crashes and then goes online again) the Client does connect to the Server, but after 2,3 seconds it throws a SocketException: Connection reset. I don't know what is causing it and i would really apprechiate it if someone could help me figure this out.
Server code that handles the clients:
public ServerHandler(Socket socket){
try{
pw = new PrintWriter(socket.getOutputStream());
writerHolder[userCounter] = pw;
InputStreamReader in = new InputStreamReader(socket.getInputStream());
reader = new BufferedReader(in);
userCounter++;// Increment the number of people connected
}catch(Exception ex)
{
ex.printStackTrace();
}
}
Client code that connects to the Server:
private void startConnection()
{
try
{
sock = new Socket("192.168.1.5", 5000);
InputStreamReader input = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(input);
pw = new PrintWriter(sock.getOutputStream());
JOptionPane.showMessageDialog(null, "Connected to the server!");
}catch(IOException ex)
{
//timer.reconnectTimer(20);
ex.printStackTrace();
}
}
StackTrace:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at homeControl.ServerHandler.run(ServerHandler.java:52)
at java.lang.Thread.run(Unknown Source)
"Connection reset" usually means that the remote side closed its side of the socket without reading the data that you sent. Make sure that you read data sent to you before you close a socket.
Related
In the client-server socket program below, the client is sending data to server which is listening on port 3500, but here the server is not sending any data back to client, so in the client socket program, i do not read from then input stream then am getting socket exception, socket write error.
below is the server code:
private static ServerSocket sc = null;
private static final int port = 3500;
public static void main(String args[]) throws IOException{
try {
sc = new ServerSocket(port);
while(true){
Socket socket = sc.accept();
System.out.println("Listening on port <=> "+port);
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Received Request <=>"+message);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("Hi Client received your message<=>"+message);
ois.close();
oos.close();
socket.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Client socket code below:
try {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
Socket clientsocket = null;
for(int i=0;i<2;i++){
clientsocket = new Socket(InetAddress.getLocalHost().getHostName(), 3500);
oos = new ObjectOutputStream(clientsocket.getOutputStream());
oos.writeObject("Client Request: "+i);
//ois = new ObjectInputStream(clientsocket.getInputStream());
//String message = (String) ois.readObject();
//System.out.println("Message sent by Server: " + message);
//ois.close();
oos.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In the above code, if the comments are removed then the code is working fine, but confused why the input stream should be read when there is no data to be read.
Getting below exception after commenting the input stream section as done above.
Listening on port <=> 3500
Received Request <=>Client Request: 0
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(Unknown Source)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(Unknown Source)
at java.io.ObjectOutputStream.writeNonProxyDesc(Unknown Source)
at java.io.ObjectOutputStream.writeClassDesc(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeFatalException(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at com.springexercise.demo.ServerTest.main(ServerTest.java:28)
The error is because you close the connection on the client side before the server has a chance to write data into the stream.
If you remove the
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("Hi Client received your message<=>"+message);
....
oos.close();
part the error should be resolved because the server is no longer trying to write on a closed connection.
If you have the client reading part in the code the whole process works because the client wait for new data in the connection. That leads to the situation where the connection is still open when the server tries to write and everything is working as expected from the java site.
I am trying to test my chat client application by creating a socket and connecting it to the server, sending a message and closing the socket (via the server's close method). However, it seems that when I close the socket the client thread still awaits for client input. However, I have put if clause to stop it from waiting. Here is my test:
#Test
public void testMessagesReceived() throws IOException
{
ServerSocket s = server.getSocket();
System.out.println(s);
mysocket = new Socket("127.0.0.1", 3000);
final PrintWriter stream = new PrintWriter(mysocket.getOutputStream(), true);
stream.println("Default room");
}
#AfterSuite
public void stopServer() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
server.stop();
}
However, when the server.stop() executes and closes the socket I get an exception in the client thread which is alive and uses this socket, here:
public void acceptFromConsole() throws IOException {
if (!socket.isClosed()) {
final BufferedReader fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message;
while ((message = fromClient.readLine()) != null) { // Exception here
if (message.contains(TelnetUtilities.Quit.toString())) {
room.removeClient(id);
break;
}
}
Here is the full stacktrace:
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 sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at com.egt.chat.server.ClientContainer.acceptFromConsole(ClientContainer.java:40)
at com.egt.chat.server.ClientContainerRunnable.run(ClientContainerRunnable.java:28)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
It seems to me that in one thread I close the socket ,however the client thread doesn't see the change on the socket and that check if(!socket.isClosed()) returns true and the flow of execution continues and while I try to read it of course throws exception that I am trying to read from a closed socket ,is there a way to overcome this?
Your code is working as it should be. When you forcefully disconnect the socket your code is the while loop:
while ((message = fromClient.readLine()) != null) { // Exception here
if (message.contains(TelnetUtilities.Quit.toString())) {
room.removeClient(id);
break;
}
readLine() is waiting for incoming data. If you would not close the connection it would wait forever for new data. Then you close the connection and readLine() (or better the underlaying socketRead method) now recognizes that it can't read data from a closed socket and raises the exception.
Therefore this exception is an expected exception at this point. Catch it and be happy.
I would do it this way: Add a boolean variable like stopServerCalled which is by default false and is set to true when stopServer() is called.
try {
while ((message = fromClient.readLine()) != null) { // Exception here
if (message.contains(TelnetUtilities.Quit.toString())) {
room.removeClient(id);
break;
}
} catch (SocketException e) {
// check if this is an expected exception and if yes ignore it
if (!stopServerCalled)
throw e;
}
I understand why the binding error occurs, but I have followed any solution I can find and cannot get it to work.
Stack Trace
java.net.BindException: Address already in use: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at socket.ClientWorker.run(ClientWorker.java:30)
at java.lang.Thread.run(Unknown Source)
Picked up JAVA_TOOL_OPTIONS: -Djava.vendor="Sun Microsystems Inc"
Server Code
#Override
public void run() {
try {
ServerSocket listener = new ServerSocket(port);
while (running) {
Socket socket = listener.accept();
new Thread(new ServerWorker(socket, airport)).start();
}
listener.close();
} catch (IOException e) {e.printStackTrace();}
}
Each time the server gets an incoming connection, it creates a new thread to do the work.
Server Worker
#Override
public void run() {
try {
// Get message
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number;
number = br.readLine();
// Add new arrival event
String[] splitMessage = number.split(" ");
String mode = splitMessage[2];
int time = Integer.valueOf(splitMessage[0]);
int airportID = Integer.valueOf(splitMessage[1]);
if(mode.equals("STANDARD")){
Event newEvent = new Event(EventType.ARRIVAL,time,airport);
airport.scheduleEvent(airportID,newEvent);
}
if(mode.equals("NULL")){
Event newEvent = new Event(EventType.NULL,time,airport);
airport.scheduleEvent(airportID,newEvent);
}
// Close
socket.close();
}
catch (IOException e){e.printStackTrace();}
}
Client
/*-- Send a message to a different airport --*/
public void sendMessage(int port, String message){
new Thread(new ClientWorker(port, message)).start();
}
The Client (airport object) calls this message when it want's to communicate with a different airport. A new thread is created to process the work.
Client Worker
#Override
public void run() {
try {
Socket s = new Socket("localhost", port);
OutputStream os = s.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String sendMessage = message + "\n";
bw.write(sendMessage);
bw.flush();
s.close();
}
catch (UnknownHostException e){e.printStackTrace(); System.exit(0);}
catch (IOException e){e.printStackTrace(); System.exit(0);}
}
The error traces back to here - 'Socket s = new Socket("localhost", port);'
Notes
All work is done on the same machine.
Hundreds of messages could be sent each second.
All the clients are running in parallel.
The client may have to send multiple messages in (very) quick succession.
I thought I was making a new connection per message, but I must be misunderstanding something.
you are using Socket socket = listener.accept(); you need to close socket after use into server code.
`
You're probably exhausting the number of client connections you can concurrently establish; in that case abusing ServerSocket#setReuseAddress() probably isn't a good idea.
I thought I was making a new connection per message, but I must be misunderstanding something.
You are- that's the problem :) Consider some kind of connection-pooling to reuse existing connections rather than spinning up thousands at a time (if your client and server spans across hosts, even the overhead of establishing the connection could quickly become the bottleneck in a setup like this).
I'm nowhere near done with this project yet I'm just trying to make sure things are working and more specifically that the client and server are connecting, and I'm getting connection errors. Here are my two programs. I'm also not entirely sure how to run both of them at once in eclipse so maybe that is the problem. Any help is much appreciated
import java.net.*;
import java.util.*;
import java.io.*;
public class Server {
public void main(String[] args)throws Exception {
ServerSocket server = new ServerSocket(3333);;
while (true)
{
Socket clientsocket = server.accept();
Scanner sc = new Scanner(clientsocket.getInputStream());
PrintStream p = new PrintStream(clientsocket.getOutputStream());
String message = "Hello from server";
p.print(message);
}
}
And heres the client
public static void main(String[] args)throws Exception {
Client display = new Client();
display.setVisible(true);
try {
Socket server = new Socket("localhost", 3333);
Scanner sc = new Scanner(server.getInputStream());
PrintStream p = new PrintStream(server.getOutputStream());
System.out.println(sc.next());
server.close();
sc.close();
p.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I have some gui stuff above and below the client that I didnt show. When I run these I get the following errors
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.main(Client.java:56)
and line 56 is the line with -- Socket server = new Socket("localhost", 3333);
I've tried making a simple server to accept multiple sockets & then let them input and receive an output.
But it seems like I am doing it wrong as I am getting many errors.
Is the way I am trying to do that bad? How can I do that in a better way?
I dont understand why do I get these errors:
Starting up..
Trying to listen...
Server is successfully running on port 43594
New connection: /127.0.0.1:60639
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Client.getInputStream(Client.java:29)
at ClientHandler.run(ClientHandler.java:19)
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Client.getInputStream(Client.java:29)
at ClientHandler.run(ClientHandler.java:19)
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Client.getInputStream(Client.java:29)
at ClientHandler.run(ClientHandler.java:19)
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Client.getInputStream(Client.java:29)
at ClientHandler.run(ClientHandler.java:19)
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Client.getInputStream(Client.java:29)
at ClientHandler.run(ClientHandler.java:19)
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Client.getInputStream(Client.java:29)
at ClientHandler.run(ClientHandler.java:19)
And many many more lines of errors. Its basically looping the same error over and over, but why?
I've commented the code so you can see what i've tried to do and maybe fix the way I do that.
public class Server {
private int port = 43594;
public void listen() {
System.out.println("Trying to listen...");
try {
final ServerSocket server = new ServerSocket(port);
// Create new thread to handle clients I/O
ClientHandler handler = new ClientHandler(server);
// START it
handler.start();
System.out.println("Server is successfully running on port " + port);
while (true) {
// New connection found create a new Client object
Client cl = new Client(server.accept());
cl.setup();
// add it to clietns list in the I/O handler
handler.clients.add(cl);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// start up
System.out.println("Starting up..");
// server instance
final Server server = new Server();
// create a new thread for server
new Thread(new Runnable() {
#Override
public void run() {
// listen for new connections
server.listen();
}
}).start();
}
}
public class ClientHandler extends Thread {
private Thread handler;
public ArrayList<Client> clients = new ArrayList<Client>(); // client list
private ServerSocket server;
public ClientHandler(ServerSocket s) {
server = s;
}
public void run() {
while(true) {
// Loop every time through every client and see if he has wrote
// anything to do server. I am 100% sure this is wrong, how can I do this
// without using multithreads (thread per client)?
for (Client c : this.clients) {
if (c.getInputStream() != null) {
// found input, return a message.
c.sendMessage("hey client");
}
}
try {
// sleep for 100ms
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Client {
private Socket socket;
private int clientId;
private BufferedReader inStream;
private PrintWriter outStream;
private boolean socketAlive = true;
public Client(Socket sock) {
this.socket = sock;
}
public void setup() {
setInputOutputStream();
System.out.println("New connection: " + this.getIpAddress());
this.sendMessage("Successfully connected!");
}
public String getInputStream() {
String toReturn = "";
try {
toReturn = this.inStream.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return toReturn;
}
private void setInputOutputStream() {
try {
inStream = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
outStream = new PrintWriter(this.socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String s) {
this.outStream.println(s);
this.outStream.flush();
}
public String getIpAddress() {
return this.socket.getRemoteSocketAddress().toString();
}
}
And not sure if it will be useful, this is the client:
public class TestClient {
/**
* #param args
* #throws IOException
* #throws UnknownHostException
*/
public static void main(String[] args) {
try {
System.out.println("Client started");
Socket sock = new Socket("localhost", 43594);
Scanner scanner = new Scanner(System.in);
String input;
PrintWriter out = new PrintWriter(sock.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
input = scanner.nextLine();
if (input != null) {
out.print(input);
}
if (reader.toString() != null) {
System.out.println(reader.toString());
}
} catch (IOException e) {
System.out.println("Client error");
}
}
}
Why is the connection keeps getting reset?
The client has no loop or delay, so it would just immediately quit as soon as it sent data. When a program quits, the operating system always closes all of its network connections!
Also, I don't think this does what you want it to do: System.out.println(reader.toString());. Check the output of the client!
You are writing things from the server that you aren't reading at the client. Instead the client just exits after the print. 'reader.toString() doesn't do any I/O. You need to call a read method.