While loop with Sockets and Threads does not close when expected - java

I am trying to create a method where a server would run a while loop waiting for enough clients to join. When clients send a string containing "JOIN", the server should create a new thread, update the number of clients connected and run the while loop again. The issue I have is that when I get the client to join, my server updates the number of clients joined, but does not close the loop to check the while statement again and run the loop accordingly.
I am not really sure why it is happening. I have tried to somehow return the run() method of the thread created, but that seems to have no effect on the loop.
public void handleConnection()throws IOException{
while(participants.size() < parts){
System.out.println("Current amount of participants joined: " + participants.size() + " out of " + parts);
s = ss.accept();
System.out.println("New client connection attempt from port " + s.getPort());
CoordinatorThread thread = new CoordinatorThread(s);
//System.out.println("Thread created");
synchronized (participantThreads){
participantThreads.put(thread, s.getPort());
}
//System.out.println("Starting thread");
thread.start();
}
System.out.println("All participants joined:");
int no = 1;
for(int i : participants){
System.out.println(no + ") " + i);
no++;
}
}
public class CoordinatorThread extends Thread{
private PrintWriter pr;
private InputStreamReader in;
private BufferedReader bf;
private Socket socket;
private int pport;
//private boolean joined = false;
public CoordinatorThread(Socket s) throws IOException {
socket = s;
in = new InputStreamReader(socket.getInputStream());
bf = new BufferedReader(in);
pr = new PrintWriter(socket.getOutputStream());
}
public void run(){
String str = null;
try {
str = bf.readLine();
System.out.println("Str: " + str);
} catch (IOException e) {
e.printStackTrace();
}
if(str != null && str.contains("JOIN")){
System.out.println("Not null and contains JOIN");
String[] splitStr = str.split(" ");
pport = Integer.parseInt(splitStr[1]);
participants.add(pport);
pr.println(pport + " join accepted");
pr.flush();
System.out.println("COORD: A new participant has joined - " + pport + " / " + socket.getPort()+"\n" +
"total participants: " + participants.size());
}
}
}
The participant class is simply client class with a socket that connects to the coordinator and sends "JOIN " to join the server.

Related

What is the problem of this code...? Java socket programming

I am coding client-server multithread calculator using java, socket programming.
There's any syntax error, but msgs cannot be received from server.
I think
receiveString = inFromServer.readLine()
does not works. This code is in Client program, in the while(true) loop.
What is the problem?
Here is my full code.
SERVER
import java.io.*;
import java.net.*;
public class Server implements Runnable
{
static int max = 5; //maximum thread's number
static int i = 0, count = 0; //i for for-loop, count for count number of threads
public static void main(String args[]) throws IOException
{
ServerSocket serverSocket = new ServerSocket(6789); //open new socket
File file = new File("src/serverinfo.dat"); //make data file to save server info.
System.out.println("Maximum 5 users can be supported.\nWaiting...");
for(i=0; i <= max; i++) { new Connection(serverSocket); } //make sockets - loop for max(=5) times
try //server information file writing
{
String dataString = "Max thread = 5\nServer IP = 127.0.0.1\nServer socket = 6789\n";
#SuppressWarnings("resource")
FileWriter dataFile = new FileWriter(file);
dataFile.write(dataString);
}
catch(FileNotFoundException e) { e.printStackTrace(); }
catch(IOException e) { e.printStackTrace(); }
}
static class Connection extends Thread
{
private ServerSocket serverSocket;
public Connection(ServerSocket serverSock)
{
this.serverSocket = serverSock;
start();
}
public void run()
{
Socket acceptSocket = null;
BufferedReader inFromClient = null;
DataOutputStream msgToClient = null;
String receiveString = null;
String result = "", sys_msg = "";
try
{
while(true)
{
acceptSocket = serverSocket.accept(); // 접속수락 소켓
count++;
inFromClient = new BufferedReader(new InputStreamReader(acceptSocket.getInputStream()));
msgToClient = new DataOutputStream(acceptSocket.getOutputStream());
System.out.println(count + "th client connected: " + acceptSocket.getInetAddress().getHostName() + " " + count + "/" + max);
System.out.println("Waiting response...");
while(true)
{
if (count >= max+1) // if 6th client tries to access
{
System.out.println("Server is too busy. " + max + " clients are already connected. Client access denied.");
sys_msg = "DENIED";
msgToClient.writeBytes(sys_msg);
acceptSocket.close();
count--;
break;
}
try{ msgToClient.writeBytes(result); }
catch(Exception e) {}
try{ receiveString = inFromClient.readLine(); }
catch(Exception e) // if receiveString = null
{
System.out.println("Connection Close");
count--;
break;
}
System.out.println("Input from client : " + receiveString);
try
{
if(receiveString.indexOf("+") != -1) { result = cal("+", receiveString); }
else if(receiveString.indexOf("-") != -1) { result = cal("-", receiveString); }
else if(receiveString.indexOf("/") != -1) { result = cal("/", receiveString); }
else if(receiveString.indexOf("*") != -1) { result = cal("*", receiveString); }
else if(receiveString.indexOf("+") == -1 || receiveString.indexOf("-") == -1 || receiveString.indexOf("*") == -1 || receiveString.indexOf("/") == -1) { result = "No INPUT or Invalid operation"; }
}
catch(Exception e){ result = "Wrong INPUT"; }
try{ msgToClient.writeBytes(result); }
catch(Exception e) {}
}
}
}
catch(IOException e) { e.printStackTrace(); }
}
}
private static String cal(String op, String recv) //function for calculating
{
double digit1, digit2; //first number, second number
String result = null;
digit1 = Integer.parseInt(recv.substring(0, recv.indexOf(op)).trim());
digit2 = Integer.parseInt(recv.substring(recv.indexOf(op)+1, recv.length()).trim());
if(op.equals("+")) { result = digit1 + " + " + digit2 + " = " + (digit1 + digit2); }
else if(op.equals("-")) { result = digit1 + " - " + digit2 + " = " + (digit1 - digit2); }
else if(op.equals("*")) { result = digit1 + " * " + digit2 + " = " + (digit1 * digit2); }
else if(op.equals("/"))
{
if(digit2 == 0){ result = "ERROR OCCURRED: Cannot be divided by ZERO"; }
else{ result = digit1 + " / " + digit2 + " = " + (digit1 / digit2); }
}
return result;
}
#Override
public void run() {
// TODO Auto-generated method stub
}
}
-----------------------------------------------------------------
CLIENT
import java.io.*;
import java.net.*;
public class Client {
public static void main(String args[]) throws IOException
{
Socket clientSocket = null;
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
BufferedReader inFromServer = null;
DataOutputStream msgToServer = null;
String sendString = "", receiveString = "";
try
{
clientSocket = new Socket("127.0.0.1", 6789); //make new clientSocket
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
msgToServer = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Input exit to terminate");
System.out.println("Connection Success... Waiting for permission");
while(true)
{
receiveString = inFromServer.readLine();
if(receiveString.equals("DENIED"))
{
System.out.println("Server is full. Try again later.");
break;
}
else { System.out.println("Connection permitted."); }
System.out.print("Input an expression to calculate(ex. 3+1): ");
sendString = userInput.readLine();
if(sendString.equalsIgnoreCase("exit")) //when user input is "exit" -> terminate
{
clientSocket.close();
System.out.println("Program terminated.");
break;
}
try { msgToServer.writeBytes(sendString); }
catch(Exception e) {}
try { receiveString = userInput.readLine(); }
catch(Exception e) {}
System.out.println("Result: " + receiveString); //print result
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
You've set up your server socket stack wrong.
Your code will make 5 threads, each calling accept on a serversocket.
The idea is to have a single ServerSocket (and not 5, as in your example). Then, this single serversocket (running in a single thread that handles incoming sockets flowing out of this serversocket) will call .accept which will block (freeze the thread) until a connection is made, and will then return a Socket object. You'd then spin off a thread to handle the socket object, and go right back to the accept call. If you want to 'pool' (which is not a bad idea), then disassociate the notion of 'handles connections' from 'extends Thread'. For example, implement Runnable instead. Then pre-create the entire pool (for example, 10 threads), have some code that lets you 'grab a thread' from the pool and 'return a thread' to the pool, and now the serversocket thread will, upon accept returning a socket object, grab a thread from the pool (which will block, thus also blocking any incoming clients, if every thread in the pool is already taken out and busy handling a connection), until a thread returns to the pool. Alternatively, the serversocket code checks if the pool is completely drained and if so, will put on a final thread the job of responding to that client 'no can do, we are full right now'.
I'm not sure if you actually want that; just.. make 1 thread per incoming socket is a lot simpler. I wouldn't dive into pool concepts until you really need them, and if you do, I'd look for libraries that help manage them. I think further advice on that goes beyond the scope of this question, so I'll leave the first paragraph as an outlay of how ServerSocket code ought to work, for context.

java.net.SocketException: Connection reset by peer. In custom twitch bot

I created custom Twitch bot with using of cavariux library. I called this methods in main class.
bot.setOauth_Key("oauth:key_Value");
bot.connect();
bot.joinChannel(channel.toString());
bot.start();
Approximately one of the 5-6 launches of the bot is accompanied by an exception
java.net.SocketException: Connection reset by peer
. The stack trace indicates that the exception starts on this line.
while ((line = this.reader.readLine( )) != null && !stopped)
in TwitchBot class in method start(). I didn't change code of this library except adding utf encoding in method connect(String ip, int port).
this.writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
I've tested my bot on different PCs. On some machines I don't have this issue. On some I got this exception more often.
This is code of method start() in TwitchBot class.
public final void start()
{
if (isRunning()) return;
String line = "";
stopped = false;
try {
while ((line = this.reader.readLine( )) != null && !stopped) {
if (line.toLowerCase( ).startsWith("ping")) {
LOGGER.log(Level.INFO,"> PING");
LOGGER.log(Level.INFO,"< PONG " + line.substring(5));
this.writer.write("PONG " + line.substring(5) + "\r\n");
this.writer.flush();
} else if (line.contains("PRIVMSG"))
{
String str[];
str = line.split("!");
final User msg_user = User.getUser(str[0].substring(1, str[0].length()));
str = line.split(" ");
Channel msg_channel;
msg_channel = Channel.getChannel(str[2], this);
String msg_msg = line.substring((str[0].length() + str[1].length() + str[2].length() + 4), line.length());
LOGGER.log(Level.INFO,"> " + msg_channel + " | " + msg_user + " >> " + msg_msg);
if (msg_msg.startsWith(commandTrigger))
onCommand(msg_user, msg_channel, msg_msg.substring(1));
if (msg_user.toString().equals("jtv") && msg_msg.contains("now hosting")) {
String hoster = msg_msg.split(" ")[0];
onHost(User.getUser(hoster), msg_channel);
}
onMessage(msg_user, msg_channel, msg_msg);
} else if (line.contains(" JOIN ")) {
String[] p = line.split(" ");
String[] pd = line.split("!");
if (p[1].equals("JOIN"))
userJoins(User.getUser(pd[0].substring(1)), Channel.getChannel(p[2], this));
} else if (line.contains(" PART ")) {
String[] p = line.split(" ");
String[] pd = line.split("!");
if (p[1].equals("PART"))
userParts(User.getUser(pd[0].substring(1)), Channel.getChannel(p[2], this));
} else if (line.contains(" WHISPER ")) {
String[] parts = line.split(":");
final User wsp_user = User.getUser(parts[1].split("!")[0]);
String message = parts[2];
onWhisper(wsp_user, message);
} else if (line.startsWith(":tmi.twitch.tv ROOMSTATE")) {
} else if (line.startsWith(":tmi.twitch.tv NOTICE"))
{
String[] parts = line.split(" ");
if (line.contains("This room is now in slow mode. You may send messages every"))
{
LOGGER.log(Level.INFO,"> Chat is now in slow mode. You can send messages every " + parts[15] + " sec(s)!");
} else if (line.contains("subscribers-only mode")) {
if (line.contains("This room is no longer"))
LOGGER.log(Level.INFO,"> The room is no longer Subscribers Only!");
else
LOGGER.log(Level.INFO,"> The room has been set to Subscribers Only!");
} else {
LOGGER.log(Level.INFO,line);
}
} else if (line.startsWith(":jtv MODE "))
{
String[] p = line.split(" ");
if (p[3].equals("+o")) {
LOGGER.log(Level.INFO,"> +o " + p[4]);
} else {
LOGGER.log(Level.INFO,"> -o " + p[4]);
}
} else if (line.toLowerCase().contains("disconnected"))
{
LOGGER.log(Level.INFO, line);
this.connect();
} else
{
LOGGER.log(Level.INFO,"> " + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
This is code of method connect() in TwitchBot class.
public void connect(String ip, int port)
{
if (isRunning()) return;
try{
if (user == null || user == "")
{
LOGGER.log(Level.SEVERE, "Please select a valid Username");
System.exit(1);
return;
}
if (oauth_key == null || oauth_key == "")
{
LOGGER.log(Level.SEVERE,"Please select a valid Oauth_Key");
System.exit(2);
return;
}
#SuppressWarnings("resource")
Socket socket = new Socket(ip, port);
this.writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream(),StandardCharsets.UTF_8));
this.writer.write("PASS " + oauth_key + "\r\n");
this.writer.write("NICK " + user + "\r\n");
this.writer.write("USER " + this.getVersion() + " \r\n");
this.writer.write("CAP REQ :twitch.tv/commands \r\n");
this.writer.write("CAP REQ :twitch.tv/membership \r\n");
this.writer.flush();
String line = "";
while ((line = this.reader.readLine()) != null)
{
if (line.indexOf("004") >= 0) {
LOGGER.log(Level.INFO,"Connected >> " + user + " ~ irc.twitch.tv");
break;
}else {
LOGGER.log(Level.INFO,line);
}
}
} catch (IOException e)
{
e.printStackTrace();
}
}
Thank you for the help
This error means that the peer (i.e. the Twitch server) closes abruptly your connection. See this answer for more details.
I don't know if you can do something to fix that because it can have various external origins (peer crash...). Maybe you can wait and try to reconnect later (note that you might be blacklisted if you connect too often).

Java TCP Connection Socket not writing to output stream

I am writing a server for a game which I am coding in java. The output stream won't actually send the information back to the client for some reason. I have tried everything, however closing the socket ends up in the program erroring because of the socket closing before it has written to the output stream. I am unable to figure out why.
EDIT: I have put a lot of the code in this gist. Also, for clarification, the response wasn't sending at all, even if I didn't close the socket. The client was simply waiting for an answer, and not receiving one.
Here is my code.
public class ServerThread extends Thread {
private Socket clientSocket;
private List<Player> players;
public Player player = null;
public ServerThread (Socket clientSocket, List<Player> players)
{
this.clientSocket = clientSocket;
this.players = players;
}
public void run()
{
try {
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
DataOutputStream os = new DataOutputStream(clientSocket.getOutputStream());
String req = br.readLine();
br.close();
String response = buildResponse(req);
os.writeBytes(response);
os.flush();
System.out.println("Sending [ " + response + " ] to " + clientSocket.getInetAddress().getHostAddress());
player = addPlayerFromRequest(req);
} catch (IOException ex) {
Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
}
try {
clientSocket.close();
} catch (IOException ex) {
Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String buildResponse(String req)
{
List<Player> plays;
plays = players;
String name = req.split(",")[0];
String response = "";
if (plays.size() <= 1) {
return response;
}
for (int i = 0; i < plays.size(); i++) {
Player p = plays.get(i);
if (!p.name.equals(name)) {
response += p.name + "," + p.x + "," + p.y + "," + p.z + "," + p.rx + "," + p.rx + "," + p.rz + ";";
}
}
return response;
}
public Player addPlayerFromRequest (String req)
{
String[] list = req.split(",");
String user = list[0];
float x = Float.parseFloat(list[1]);
float y = Float.parseFloat(list[2]);
float z = Float.parseFloat(list[3]);
float rx = Float.parseFloat(list[4]);
float ry = Float.parseFloat(list[5]);
float rz = Float.parseFloat(list[6]);
return new Player(x, y, z, rx, ry, rz, user);
}
}
This code will throw SocketException: Socket closed because of br.close(), but assuming you've removed that, I suggest that your client is reading lines but you aren't sending lines. Add a line terminator to the message, or use BufferedWriter.newLine().

proxy in java only showing 1 server reply

I have posted my java proxy code below.
It works but it only gives me 1 server response instead of everything.
After the 1 response I just get client sent packets but with a size of 0.
Screenshots also attached.
Any ideas?
I've done some debugging. If I remove everything in between
typ = streamFromServer.readUnsignedShort();
siz = streamFromServer.readUnsignedShort();
siz <<= 8;
siz |= streamFromServer.readUnsignedByte();
byte[] dat = new byte[siz];
streamFromServer.readFully(dat, 0, siz);
String FullHe = DatatypeConverter.printHexBinary(dat);
System.out.println("Server sending data to Client:");
System.out.println("Type: " + typ + "");
System.out.println("Data Size: " + siz + "");
System.out.println("Full Data: " + FullHe + "");
System.out.println("\n\n");
Which is from the reading server response code it works and I get the client packets. How come it doesn't work with server packets?
Code:
import java.io.*;
import javax.xml.bind.DatatypeConverter;
import java.net.*;
public class proxy{
public static void main(String[] args) throws IOException {
//PrintStream out = new PrintStream(new FileOutputStream("log.txt"));
//System.setOut(out);
try{
String host = "gamea.clashofclans.com";
int remoteport = 9339;
ServerSocket ss = new ServerSocket(9339);
int localport = ss.getLocalPort();
ss.setReuseAddress(true);
// Print a start-up message
System.out.println("Starting proxy for " + host + ":" + remoteport
+ " on port " + localport);
// And start running the server
runServer(host, remoteport, localport,ss); // never returns
System.out.println("Started proxy!");
} catch (Exception e) {
System.out.println("Failed to start proxy" +e+ "");
}
}
public static void runServer(String host, int remoteport, int localport, ServerSocket ss)
throws IOException {
final byte[] request = new byte[2048];
byte[] reply = new byte[4096];
while (true) {
Socket client = null, server = null;
try {
System.out.println("Waiting for Client");
client = ss.accept();
System.out.println("Client Accepted!");
DataInputStream streamFromClient = new DataInputStream(client.getInputStream());
DataOutputStream streamToClient = new DataOutputStream(client.getOutputStream());
System.out.println("Connecting to server...");
// Make a connection to the real server.
server = new Socket("gamea.clashofclans.com", 9339);
System.out.println("Just connected client to " + server.getRemoteSocketAddress());
DataInputStream streamFromServer = new DataInputStream(server.getInputStream());
DataOutputStream streamToServer = new DataOutputStream(server.getOutputStream());
Thread t = new Thread() {
public void run() {
int bytesRead;
int type;
int size;
int version;
try {
while ((bytesRead = streamFromClient.read(request)) != -1) {
type = streamFromClient.readUnsignedShort();
size = streamFromClient.readUnsignedShort();
size <<= 8;
size |= streamFromClient.readUnsignedByte();
version = streamFromClient.readUnsignedByte();
byte[] data = new byte[size];
streamFromClient.readFully(data, 0, size);
String FullHex = DatatypeConverter.printHexBinary(data);
System.out.println("Client sending data to server:");
System.out.println("Type: " + type + "");
System.out.println("Data Size: " + size + "");
System.out.println("Version: " + version + "");
System.out.println("Full Data: " + FullHex + "");
System.out.println("\n\n");
streamToServer.write(request, 0, bytesRead);
streamToServer.flush();
}
} catch (IOException e) {
}
// the client closed the connection to us, so close our
// connection to the server.
try {
streamToServer.close();
} catch (IOException e) {
}
}
};
t.start();
int bytesRea;
int typ;
int siz;
try {
while ((bytesRea = streamFromServer.read(reply)) != -1) {
typ = streamFromServer.readUnsignedShort();
siz = streamFromServer.readUnsignedShort();
siz <<= 8;
siz |= streamFromServer.readUnsignedByte();
byte[] dat = new byte[siz];
streamFromServer.readFully(dat, 0, siz);
String FullHe = DatatypeConverter.printHexBinary(dat);
System.out.println("Server sending data to Client:");
System.out.println("Type: " + typ + "");
System.out.println("Data Size: " + siz + "");
System.out.println("Full Data: " + FullHe + "");
System.out.println("\n\n");
streamToClient.write(reply, 0, bytesRea);
streamToClient.flush();
}
} catch (IOException e) {
}
} catch (IOException e) {
System.err.println(e);
} finally {
try {
if (server != null)
server.close();
if (client != null)
client.close();
} catch (IOException e) {
}
}
}
}
}
This doesn't make sense. You're reading up to 4096 bytes from the server and then reading two type bytes and three length bytes and what you think is the request data, and writing what you read originally. So you're consuming the data about twice.
This can't work. You need to either just read the type, length, and value, and write them out again, or else, much more simply, just copy bytes from the input to the output, in both directions. (That way of course you can't do logging.)
NB Don't ignore IOExceptions, and especially not EOFExceptions when reading from DataInputStreams (or ObjectInputStreams).

How to check if client has disconnected? [duplicate]

This question already has answers here:
Java detect lost connection [duplicate]
(9 answers)
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 9 years ago.
I have a java program with Socket. I need to check if client has disconnected. I need a example how to do that. I have researched but I don't understand. So can someone make example code and explane everything.
sorry for bad English
my code:
package proov_server;
//SERVER 2
import java.io.*;
import java.net.*;
class server2 {
InetAddress[] kasutaja_aadress = new InetAddress[1000];
String newLine = System.getProperty("line.separator");
int kliendiNr = 0;
int kilene_kokku;
server2(int port) {
try {
ServerSocket severi_pistik = new ServerSocket(port);
System.out.println("Server töötab ja kuulab porti " + port + ".");
while (true) {
Socket pistik = severi_pistik.accept();
kliendiNr++;
kasutaja_aadress[kliendiNr] = pistik.getInetAddress();
System.out.println(newLine+"Klient " + kliendiNr + " masinast "
+ kasutaja_aadress[kliendiNr].getHostName() + " (IP:"
+ kasutaja_aadress[kliendiNr].getHostAddress() + ")");
// uue kliendi lõime loomine
KliendiLoim klient = new KliendiLoim(pistik,kliendiNr);
// kliendi lõime käivitamine
klient.start();
}
}
catch (Exception e) {
System.out.println("Serveri erind: " + e);
}
}
DataOutputStream[] väljund = new DataOutputStream[1000];
DataInputStream[] sisend = new DataInputStream[1000];
int klient = 0;
int nr;
// sisemine klass ühendusega tegelemiseks
class KliendiLoim extends Thread {
// kliendi pistik
Socket pistik;
// kliendi number
KliendiLoim(Socket pistik2,int kliendiNr) {
nr = kliendiNr;
this.pistik = pistik2;
}
public boolean kontroll(){
try{
System.out.println("con "+pistik.isConnected());
System.out.println("close "+pistik.isClosed());
if(pistik.isConnected() && !pistik.isClosed()){
//System.out.print(con_klient);
return true;
}
}catch(NullPointerException a){
System.out.println("Sihukest klienti pole!!!");
}
kliendiNr --;
return false;
}
public void run() {
try {
sisend[nr] = new DataInputStream(pistik.getInputStream()); //sisend
väljund[nr] = new DataOutputStream(pistik.getOutputStream()); //väljund
}catch (Exception ea) {
System.out.println(" Tekkis erind: " + ea);
}
while(true){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Sisesta k2sk: ");
String k2sk = null;
k2sk = br.readLine();
/*
String command;
if(k2sk.indexOf(" ") < 0){
command = k2sk;
}else{
command = k2sk.substring(0, k2sk.indexOf(" "));
}
*/
String[] words = k2sk.split("\\s+");
for (int i = 0; i < words.length; i++) {
words[i] = words[i].replaceAll(" ", "");
}
switch(words[0]){
case "suhtle":
if(väljund.length > klient && väljund[klient] != null)
{
väljund[klient].writeUTF("1");
}else{
väljund[klient] = null;
sisend[klient] = null;
System.out.println("Sihukest klienti pole");
}
break;
case "vaheta":
try{
int klinetnr = Integer.parseInt(words[1]);
//if(kontroll(klinetnr) ){
klient = Integer.parseInt(words[1]);
//}
}
catch(NumberFormatException e){
System.out.println("See pole number!!! ");
}
break;
case "kliendid":
if(kliendiNr != 0){
for(int i=1;i <= kliendiNr;i++){
if(kontroll()){
System.out.println("Klient:"+i+" ip: " + kasutaja_aadress[i] );
}else{
System.out.println("Pisi");
väljund[klient] = null;
sisend[klient] = null;
}
}
System.out.println(newLine);
}else{
System.out.println("Kiente pole");
}
break;
}
System.out.println(kliendiNr);
}catch(SocketException a){
System.out.println("Klient kadus");
}
catch(Exception e){
System.out.println(" Viga: " + e);
}
}
}
}
public static void main(String[] args) {
new server2(4321);
}
}
If the client has disconnected properly:
read() will return -1
readLine() returns null
readXXX() for any other X throws EOFException.
The only really reliable way to detect a lost TCP connection is to write to it. Eventually this will throw an IOException: connection reset, but it takes at least two writes due to buffering.
A related thread on Stackoverflow here along with the solution. Basically, the solution says that the best way to detect a client-server disconnect is to attempt to read from the socket. If the read is successfully, then the connection is active.If an exception is thrown during the read there is no connection between the client and the server. Alternatively it may happen that the socket is configured with a timeout value for the read operation to complete. In case, this timeout is exceeded a socket timeout exception will be thrown which can be considered as either the client is disconnected or the network is down.
The post also talks about using the isReachable method - refer InetAddress documentation. However, this method only tells us whether a remote host is reachable or not. This may just one of the reasons for the client to disconnect from the server. You wont be able to detect disconnection due to client crash or termination using this technique.

Categories

Resources