Reputation: 979
I managed to setup a server which will accept & manage multiple socket clients. but now when I try to send a message, the server just doesn't receive anything, yet I do flush the message.
This is the method that's managing the clients:
public void run() {
while(true) {
for (Client c : this.clients) {
try {
if (c.getStream().read() != -1) {
if (c.getInputStream() != null) {
System.out.println("He sent message");
c.sendMessage("hey client");
}
}
} catch (IOException e) {
c.destruct();
this.clients.remove(c); break;
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Client list:
public ArrayList<Client> clients = new ArrayList<Client>(); // client list
And Client object:
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 BufferedReader getStream() {
return this.inStream;
}
public String getInputStream() {
String toReturn = "";
try {
toReturn = this.inStream.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return toReturn;
}
public void destruct() {
try {
this.inStream.close();
this.inStream = null;
this.outStream.close();
this.outStream = null;
System.out.println("Client destruct: " + this.socket.getLocalSocketAddress());
this.socket.close();
this.socket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket getConnection() {
return this.socket;
}
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 the client side (sender) :
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()));
while (true) {
input = scanner.nextLine();
if (input != null) {
out.print(input);
out.flush();
}
}
} catch (IOException e) {
System.out.println("Client error");
}
}
Why is my server not receiving anything?
One thing:
If I send message + disconnect, this what the server will log (It looks like it only sends the message upon disconnect or something, well no, it enters the if block only upon it):
Server is successfully running on port 43594
New connection: /127.0.0.1:57102
He sent message
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:32)
at ClientHandler.run(ClientHandler.java:21)
Client destruct: 0.0.0.0/0.0.0.0:43594
What did I do wrong? how can I fix that
Server (main class)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.util.ArrayList;
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();
}
}
Upvotes: 0
Views: 2507
Reputation: 979
I am not sure why, but I needed to use out.println(input) out.flush()
instead of .print()
or .write()
I don't have an explanation of why do I need to do that. but it worked.
Upvotes: 1
Reputation: 5907
The client is sending data and the servers is reading.
I think the problem is in Client.getInputStream
this.inStream.readLine(), it reads a line of text. From documentation: "Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed."
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html
If you use read instead, maybe it is going to work. Just use a kind of protocol like sending first 1 or 2 bytes with the length of the message. Or you may send a '\n' from the client.
BTW, the reason for the exception in the server when you send and disconnect in the client side may be due to a TCP fact. The client closed the connection and it probably received a TCP ACK from the server. Then TCP in the client sends a RESET segment. Not so sure though. The server was at this.inStream.readLine() and then it received an exception. Didn't you also received "Connection closed by peer"?
Upvotes: 1
Reputation: 1005
I think the problem comes from the fact that you've got a list of clients and are trying to manage them with that. I looked up java.net.SocketException: Connection reset
, and found this question: What's causing my java.net.SocketException: Connection reset?
The answer to this question comes up with this:
In your case it seems that the connection has been closed by the server end of the connection. This could be an issue with the request you are sending or an issue at their end.
This made me think that you aren't holding the connection to the client every time. You store it, and then you lose it, so the message isn't sent. To handle more clients, you might rather want to have a list of IPs, rather than clients, and then you connect when you want to send a message. You can't store the Socket connection. It has to be active. Java (The JVM) has it's own "Garbage Collection" system that'll just kill it.
Upvotes: 0