I made a previous post a bit back working on getting a two-way server/client socket connection working. I've largely succeeded yet, but I still have one more step as a barrier. I'd like to make it so the client disconnects after they perform an operation, but the server remains up and can take in another client operation until the client makes a specific response. I'm attempting to do this through while loops in both the client and server. This is my server class:
import java.net.*;
import java.io.*;
public class ServerDemo {
private Socket mySocket = null;
private ServerSocket server = null;
private static ObjectInputStream in=null;
private static ObjectOutputStream out=null;
private static Payload myPayload=new Payload();
public ServerDemo(int port) throws ClassNotFoundException
{
double time=0;
int bytes=0;
try
{
server = new ServerSocket(port);
System.out.println("Server started");
System.out.println("Waiting for a client ...");
}
catch(IOException i)
{
System.out.println(i);
myPayload.setRepeat(false);
}
try {
while(myPayload.getRepeat()==true) {
mySocket = server.accept();
System.out.println("Client accepted");
in = new ObjectInputStream(
new BufferedInputStream(mySocket.getInputStream()));
out = new ObjectOutputStream(mySocket.getOutputStream());
myPayload.setDataPasses(10);
while (myPayload.getCurr()<myPayload.getDataPasses())
{
try
{
myPayload= (Payload) in.readObject();
myPayload.raisePasses();
out.writeObject(myPayload);
}
catch(IOException i)
{
System.out.println(i);
myPayload.setRepeat(false);
}
}
System.out.println("Closing connection");
mySocket.close();
in.close();
System.out.println("Operation Complete");
System.out.println("Client Address: "+myPayload.getClient());
System.out.println("Server Address: "+myPayload.getServer());
time=System.nanoTime()-(myPayload.getTime());
time=time/1000000000;
System.out.println("Total Time (in seconds): "+time);
bytes=(int) ( ((myPayload.getPacket().length)*myPayload.getDataPasses())/time);
System.out.println("Bytes per Second: "+bytes);
}
}
catch(IOException i)
{
System.out.println(i);
myPayload.setRepeat(false);
}
}
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
ServerDemo server=new ServerDemo(5000);
}
}
This is my client class:
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class ClientDemo {
private Socket mySocket = null;
private ObjectInputStream in= null;
private ObjectOutputStream out = null;
private static long roundTrips=1;
private static Payload myPayload=new Payload();
public ClientDemo(String address, int port) throws ClassNotFoundException
{
int packageSize=1;
double time=0;
int bytes=0;
try
{
mySocket = new Socket(address, port);
System.out.println("Connected");
out = new ObjectOutputStream(mySocket.getOutputStream());
in = new ObjectInputStream(new BufferedInputStream(mySocket.getInputStream()));
}
catch(UnknownHostException u)
{
System.out.println(u);
}
catch(IOException i)
{
System.out.println(i);
}
while (myPayload.getCurr()<myPayload.getDataPasses())
{
try
{
if(myPayload.getCurr()==0) {
myPayload.setTime(System.nanoTime());
}
out.writeObject(myPayload);
myPayload= (Payload) in.readObject();
}
catch(IOException i)
{
System.out.println(i);
}
}
try
{
in.close();
out.close();
mySocket.close();
System.out.println("Operation Complete");
System.out.println("Client Address: "+myPayload.getClient());
System.out.println("Server Address: "+myPayload.getServer());
time=System.nanoTime()-(myPayload.getTime());
time=time/1000000000;
System.out.println("Total Time (in seconds): "+time);
bytes=(int) ( ((myPayload.getPacket().length)*myPayload.getDataPasses())/time);
System.out.println("Bytes per Second: "+bytes);
System.out.println("");
}
catch(IOException i)
{
System.out.println(i);
}
}
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
boolean isValid=false;
String response="";
int size=16384;
Scanner myScanner = new Scanner(System.in);
ClientDemo client=null;
String server="";
while (size>-1) {
System.out.println("Please enter a max data packet size. Enter -1 to end the program");
while(isValid==false) {
response=myScanner.next();
if(Long.parseLong(response)>=-1 && Long.parseLong(response)<=16384) {
isValid=true;
size=Integer.parseInt(response);
if(size>-1) {
myPayload.setPacket(fillPacket(size));
}
}
else {
System.out.println("Invalid Response. Please enter a value between 1 and 16384.");
}
}
if(size==-1) {
System.out.println("Closing server...");
myPayload.setRepeat(false);
client= new ClientDemo(server, 5000);
}
else {
isValid=false;
System.out.println("Please enter an amount of data passes.");
while(isValid==false) {
response=myScanner.next();
if(Long.parseLong(response)>=1) {
isValid=true;
roundTrips=Long.parseLong(response);
myPayload.setDataPasses(roundTrips);
}
else {
System.out.println("Invalid Response. Please enter a value of 1 or greater.");
}
}
isValid=false;
System.out.println("Please enter your client address.");
response=myScanner.next();
myPayload.setClient(response);
System.out.println("Please enter a server to connect to.");
response=myScanner.next();
server=response;
myPayload.setServer(server);
myPayload.reset();
client= new ClientDemo(server, 5000);
}
}
}
public static int[] fillPacket(int size) {
int[] thePacket= new int[size];
int current=0;
while(current<size) {
for(int counter=0;counter<100;counter++) {
if(current<size) {
thePacket[current]=counter;
current++;
}
}
}
return thePacket;
}
}
When I attempt to run both, the operation I have set up works completely fine, and entering -1 to close the program works but I run into errors when performing operations beyond that. Attempting to set size to -1 to end the program at this point causes an endless loop of
java.io.EOFException
inside ServerDemo, while entering what should be a valid packet size between 0 and 16384 instead produces an endless stream of
java.net.SocketException: Broken pipe (Write failed)
inside ClientDemo. Perhaps most strangely, the latter error only SOMETIMES occurs, not always. If anyone has any pointers on how to get this correctly working and remedying these errors, I would greatly appreciate it!
I would rather change approach. The usual one when doing this kind of stuff is create a thread to listen on your port, then, when a client connects, immediately dispatch the new task to a thread pool and continue listening.
This way not only your server will continue listening after the client disconnects, but also will be able to serve multiple clients in parallel (up to the thread pool size).
Also please use try-with-resources whenever possible to easily avoid resource leaking.
So your code could be changed to something like this:
Server class
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ServerDemo {
private int port;
private Thread listenThread;
private ExecutorService serverPool;
public ServerDemo(int port) {
this.port = port;
}
public synchronized void startServer() {
serverPool = Executors.newFixedThreadPool(4);
listenThread = new Thread(() -> {
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println(String.format("Listening on port %d", port));
System.out.println("1");
while (!Thread.interrupted()) {
System.out.println("2");
Socket clientSocket = serverSocket.accept();
System.out.println("3");
if(!Thread.currentThread().isInterrupted())
serverPool.submit(new ClientTask(clientSocket));
System.out.println("4");
}
} catch (IOException e) {
System.err.println("Error processing client connection");
e.printStackTrace();
}
System.out.println("ListenThread stopped");
}, "ListenThread");
listenThread.start();
}
public synchronized void stopServer() {
System.out.println("Stopping server...");
if (serverPool != null) {
serverPool.shutdown();
serverPool = null;
}
if(listenThread != null) {
listenThread.interrupt();
try (Socket voidSocket = new Socket("localhost", port)) {
// Void socket to unlock the accept() call
} catch (IOException e) {
}
listenThread = null;
}
}
private class ClientTask implements Runnable {
private final Socket clientSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
System.out.println("Client accepted");
Payload myPayload = new Payload();
try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(clientSocket.getInputStream()));
ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream())) {
myPayload.setDataPasses(10);
while (myPayload.getCurr() < myPayload.getDataPasses()) {
try {
myPayload = (Payload) in.readObject();
myPayload.raisePasses();
out.writeObject(myPayload);
} catch (IOException i) {
System.out.println(i);
break;
} catch (ClassNotFoundException e) {
System.err.println("Error finding class to deserialize");
e.printStackTrace();
}
}
System.out.println("Operation Complete");
System.out.println("Client Address: " + myPayload.getClient());
System.out.println("Server Address: " + myPayload.getServer());
double time = System.nanoTime() - (myPayload.getTime());
time = time / 1000000000;
System.out.println("Total Time (in seconds): " + time);
int bytes = (int) (((myPayload.getPacket().length) * myPayload.getDataPasses()) / time);
System.out.println("Bytes per Second: " + bytes);
} catch (IOException e1) {
System.err.println("Error opening client I/O streams");
e1.printStackTrace();
}
try {
System.out.println("Closing connection");
clientSocket.close();
} catch (IOException e) {
System.err.println("Error closing client connection");
e.printStackTrace();
}
if(!myPayload.getRepeat())
stopServer();
}
}
public static void main(String[] args) throws ClassNotFoundException {
ServerDemo server = new ServerDemo(5000);
server.startServer();
// do other stuff including trapping for sigterm, then call server.stopServer() if needed
}
}
Client class
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ClientDemo {
private static void executeClientJob(Payload myPayload, int port) {
double time = 0;
int bytes = 0;
try (Socket mySocket = new Socket(myPayload.getServer(), port);
ObjectOutputStream out = new ObjectOutputStream(mySocket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(mySocket.getInputStream()))) {
System.out.println("Connected");
while (myPayload.getCurr() < myPayload.getDataPasses()) {
if (myPayload.getCurr() == 0)
myPayload.setTime(System.nanoTime());
out.writeObject(myPayload);
myPayload = (Payload) in.readObject();
}
System.out.println("Operation Complete");
System.out.println("Client Address: " + myPayload.getClient());
System.out.println("Server Address: " + myPayload.getServer());
time = System.nanoTime() - (myPayload.getTime());
time = time / 1000000000;
System.out.println("Total Time (in seconds): " + time);
bytes = (int) (((myPayload.getPacket().length) * myPayload.getDataPasses()) / time);
System.out.println("Bytes per Second: " + bytes);
System.out.println("");
} catch (UnknownHostException u) {
u.printStackTrace();
} catch (IOException i) {
i.printStackTrace();
} catch (ClassNotFoundException c) {
c.printStackTrace();
}
}
private static void testAutomatic() {
for (int i = 0; i < 1; i++) {
Payload myPayload = new Payload();
myPayload.setPacket(fillPacket(40));
executeClientJob(myPayload, 5000);
}
Payload stopPayload = new Payload();
stopPayload.setRepeat(false);
executeClientJob(stopPayload, 5000);
}
private static void testInteractive() {
Payload myPayload;
boolean repeat;
do {
myPayload = readPayloadSettings();
repeat = myPayload.getRepeat();
executeClientJob(myPayload, 5000);
} while (repeat);
}
private static Payload readPayloadSettings() {
Payload ret = new Payload();
int size = 60;
#SuppressWarnings("resource")
Scanner myScanner = new Scanner(System.in);
System.out.println("Please enter a max data packet size. Enter -1 to end the program");
while (true) {
String response = myScanner.next();
if (Long.parseLong(response) >= -1 && Long.parseLong(response) <= 16384) {
size = Integer.parseInt(response);
break;
} else {
System.out.println("Invalid Response. Please enter a value between 1 and 16384.");
}
}
if (size == -1) {
System.out.println("Closing server...");
ret.setRepeat(false);
} else {
ret.setPacket(fillPacket(size));
System.out.println("Please enter an amount of data passes.");
while (true) {
String response = myScanner.next();
if (Long.parseLong(response) >= 1) {
ret.setDataPasses(Long.parseLong(response));
break;
} else {
System.out.println("Invalid Response. Please enter a value of 1 or greater.");
}
}
System.out.println("Please enter your client address.");
ret.setClient(myScanner.next());
System.out.println("Please enter a server to connect to.");
ret.setServer(myScanner.next());
}
return ret;
}
public static int[] fillPacket(int size) {
int[] thePacket = new int[size];
int current = 0;
while (current < size) {
for (int counter = 0; counter < 100; counter++) {
if (current < size) {
thePacket[current] = counter;
current++;
}
}
}
return thePacket;
}
public static void main(String[] args) throws ClassNotFoundException {
testInteractive();
//testAutomatic();
}
}
Payload class (with defaults to quick create an automatic test)
import java.io.Serializable;
public class Payload implements Serializable {
private int curr=0;
private long dataPasses=5;
private long time;
private String client="localhost";
private String server="localhost";
private int[] packet=new int[0];
private boolean repeat=true;
public Payload() {
}
public int getCurr() {
return curr;
}
public void setCurr(int curr) {
this.curr = curr;
}
public long getDataPasses() {
return dataPasses;
}
public void setDataPasses(long roundTrips) {
this.dataPasses = roundTrips;
}
public long getTime() {
return time;
}
public void setTime(long nanoTime) {
time = nanoTime;
}
public String getClient() {
return client;
}
public void setClient(String client) {
this.client = client;
}
public String getServer() {
return server;
}
public void setServer(String server) {
this.server = server;
}
public int[] getPacket() {
return packet;
}
public void setPacket(int[] packet) {
this.packet = packet;
}
public boolean getRepeat() {
return repeat;
}
public void setRepeat(boolean r) {
this.repeat = r;
}
public void reset() {
curr=0;
dataPasses=0;
}
public void raisePasses() {
curr++;
}
}
Related
I am currently programming an online chess game and wanted to host multiple server on 1 PC. It also works when I play with two players, but if I start a third player, it can't connect to server.
The code for the player:
public Socket socket;
public int PlayerID;
public ReadFromServer rfs;
public WriteToServer wts;
public void connectToServer(){
for (int i = 1;i <=3 ;i++ ) {
try {
socket = new Socket("localhost",(1000+i));
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
PlayerID = in.readInt();
System.out.println("You are Player Number:"+PlayerID);
if(PlayerID == 1){
System.out.println("Waiting for Oponent...");
}
rfs = new ReadFromServer(in);
wts = new WriteToServer(out);
Thread rT = new Thread(rfs);
Thread wT = new Thread(wts);
rT.start();
wT.start();
i = 4;
} catch(IOException e) {
System.out.println("ERROR at: connect to Server");
}
}
}
public static void main(String[] args) {
PlayerFrame pf = new PlayerFrame();
pf.connectToServer();
pf.GUI();
}
The Server code:
import java.io.*;
import java.net.*;
import java.net.InetAddress;
public class GameServer {
public int GameNumber = 3;
public ServerSocket ss;
public int numPlayers;
public int maxPlayers;
public Socket socket1;
public Socket socket2;
public ReadFromClient p1read;
public ReadFromClient p2read;
public WriteToClient p1write;
public WriteToClient p2write;
public GameServer[] gs;
public int p1x1,p1x2,p1y1,p1y2,p2x1,p2x2,p2y1,p2y2;
public GameServer(){
gs = new GameServer[GameNumber];
Thread[] server = new Thread[GameNumber];
ServerThread[] thread = new ServerThread[GameNumber];
for (int i = 0;i < gs.length ;i++ ) {
gs[i] = new GameServer((1000+i+1));
thread[i] = new ServerThread(i);
server[i] = new Thread(thread[i]);
server[i].start();
} // end of for
}
public GameServer(int i){
System.out.println("=====Game Server=====");
numPlayers = 0;
maxPlayers = 2;
try {
ss = new ServerSocket(i);
} catch(IOException e) {
System.out.println("ERROR at: Server Construction");
}
}
public void acceptConnections(){
try {
System.out.println("Waiting for connections...");
while (numPlayers < maxPlayers) {
Socket s = ss.accept();
DataInputStream in = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
numPlayers++;
out.writeInt(numPlayers);
System.out.println("Player Number "+numPlayers+" has connected");
ReadFromClient rfc = new ReadFromClient(numPlayers,in);
WriteToClient wtc = new WriteToClient(numPlayers,out);
if(numPlayers == 1){
socket1 = s;
p1read = rfc;
p1write = wtc;
Thread read1 = new Thread(p1read);
Thread write1 = new Thread(p1write);
read1.start();
write1.start();
}
else{
socket2 = s;
p2read = rfc;
p2write = wtc;
Thread read2 = new Thread(p2read);
Thread write2 = new Thread(p2write);
read2.start();
write2.start();
}
} // end of while
System.out.println("No longer accepting connections");
} catch(IOException e) {
System.out.println("ERROR at: acceptConnections");
}
}
public static void main(String[] args) {
new GameServer();
}
public class ReadFromClient implements Runnable{
public int playerID;
public DataInputStream dataIn;
public ReadFromClient(int pid, DataInputStream in){
playerID = pid;
dataIn = in;
System.out.println("RFC "+playerID+" Runnable created");
}
#Override
public void run(){
try {
while (true) {
if(playerID == 1){
p1x1 = dataIn.readInt();
p1y1 = dataIn.readInt();
p1x2 = dataIn.readInt();
p1y2 = dataIn.readInt();
}
else{
p2x1 = dataIn.readInt();
p2y1 = dataIn.readInt();
p2x2 = dataIn.readInt();
p2y2 = dataIn.readInt();
}
try {
Thread.sleep(25);
} catch(InterruptedException ex) {
System.out.println("ERROR at RFS Run");
}
} // end of while
} catch(IOException e) {
System.out.println("ERROR at: RFS");
}
}
}
public class WriteToClient implements Runnable{
public int playerID;
public DataOutputStream dataout;
public WriteToClient(int pid, DataOutputStream out){
playerID = pid;
dataout = out;
System.out.println("WTC "+playerID+" Runnable created");
}
#Override
public void run(){
try {
while (true) {
if(playerID == 1){
dataout.writeInt(p2x1);
dataout.writeInt(p2y1);
dataout.writeInt(p2x2);
dataout.writeInt(p2y2);
dataout.flush();
}
else{
dataout.writeInt(p1x1);
dataout.writeInt(p1y1);
dataout.writeInt(p1x2);
dataout.writeInt(p1y2);
dataout.flush();
}
try {
Thread.sleep(25);
} catch(InterruptedException ex) {
System.out.println("ERROR at WTC Run");
}
} // end of while
} catch(IOException e) {
System.out.println("ERROR at: WTC run");
}
}
}
public class ServerThread implements Runnable{
public int num;
public ServerThread(int i){
num = i;
}
#Override
public void run(){
gs[num].acceptConnections();
}
}
} // end of class GameServer
I don't get any errors, even though a window doesn't pop up when I run the third player, making.
Have just one ServerSocket and a single loop, and on accepting a client socket start a game running thread using that socket.
ServerSocket serverSocket = ...
ExecutorService executorService = Executors.newFixedThreadPool(4);
while (!executorService .isTerminated()) {
Socket socket = serverSocket.accept();
Runnable gameRun = () -> { ... socket ... };
// like new WorkerThread("...");
executorService .execute(gameRun);
}
executorService .shutdown();
You can do it more neat than here, the thread and passing the socket and such.
The above runs every game conversation in its own thread.
It has one main loop on the server socket, which is crucial; you should not use the same ServerSocket in two threads.
You can easily being overrung by a DoS attack (Denial of Service, by hundreds of requests). Just keep an eye on the count of the number of threads.
On request
I cannot code here an entire client-server dialog. For that you
should look at examples, that probably are way better than what
I can write here. Also my code is not compiled.
Some code snippets.
First I would not exchange binary data, but text. That makes developing and especially debugging easier. Also with chess notation everything is almost done.
Runnable gameRun = new GameRun(socket);
executorService .execute(gameRun);
class GameRun implements Runnable, Autoclosable {
final BufferedReader in;
final PrintWriter out
GameRun(Socket socket) {
in = new BufferedReader(
new InputStreamReader(
socket.getInputStream(),
StandardCharsets.UTF_8));
out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream(),
StandardCharsets.UTF_8)));
}
#Override
public void close() {
in.close();
out.close();
}
#Override
public void run() {
for (;;) {
out.println("Your move/action:");
if (!in.ready()) {
out.println("I am awaiting...");
//continue;
}
String line = in.readLine();
out.println("echo " + line);
if (line == null) {
break;
}
}
}
}
The client should do something similar.
I'm trying to teach myself Java programming. Currently I am working on some client-server code. My objective is to increment the client count before the thread is launched, and decrement the count when the thread completes. Right now, the thread just sleeps for a few seconds. You can see the full directions here:
http://archive.oreilly.com/oreillyschool/courses/java5/Homework/Projects/serverEssentials_proj.project.html
Here is the code I currently have:
RepositoryServer.java
package server;
import java.io.*;
import java.net.*;
public class RepositoryServer {
ServerSocket serverSocket = null;
int state = 0;
public void bind() throws IOException {
serverSocket = new ServerSocket(9172);
state=1;
}
public void process() throws IOException {
while (state ==1) {
Socket client = serverSocket.accept();
new RepositoryThread(client).start();
}
shutdown();
}
void shutdown() throws IOException {
if (serverSocket != null) {
serverSocket.close();
serverSocket=null;
state=0;
}
}
}
RepositoryClient.java
package client;
import java.io.*;
import java.net.*;
public class RepositoryClient {
public static void main(String[] args) throws Exception {
Socket server = new Socket("localhost", 9172);
PrintWriter toServer = new PrintWriter (server.getOutputStream(),true);
BufferedReader fromServer = new BufferedReader (new InputStreamReader(server.getInputStream()));
for (int num=0; num<3; num++) {
toServer.println("SIZE");
if (!toServer.checkError()) {
int response = Integer.valueOf(fromServer.readLine());
String value = fromServer.readLine();
if (response==0) {
System.out.println(num + ": Number of Images: "+ value);
} else if (response==-1) {
System.err.println(value);
} else {
System.err.println("Received unknown response: " +response);
}
}
}
server.close();
}
}
RepositoryThread.java
package server;
import java.io.*;
import java.net.*;
public class RepositoryThread extends Thread {
Socket client;
BufferedReader fromClient;
PrintWriter toClient;
RepositoryThread (Socket s) throws IOException {
fromClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
toClient=new PrintWriter(s.getOutputStream(), true);
client = s;
}
public void run() {
try {
while (true) {
String request = fromClient.readLine();
if (request == null) {
break;
}
if (request.equals("SIZE")) {
output("0");
} else {
//internal server error. Try to continue and keep processing
outputError("Unable to process request: "+ request);
continue;
}
}
} catch (IOException ioe) {
System.err.println("Thread processing terminated: " + ioe.getMessage());
}
try {
fromClient.close();
toClient.close();
client.close();
} catch (IOException ioe) {
System.err.println("Unable to close connection: " +ioe.getMessage());
}
}
void output(String result) {
toClient.println(0);
toClient.println(result);
}
void outputError(String error) {
toClient.println(-1);
toClient.println(error);
}
}
ServerLauncher.java
package server;
public class ServerLauncher {
public static RepositoryServer create() throws Exception {
RepositoryServer server = new RepositoryServer();
server.bind();
return server;
}
public static void main(String[] args) throws Exception {
RepositoryServer server = create();
System.out.println("Server awaiting client connections");
server.process();
System.out.println("Server shutting down.");
}
}
TestServer.java
package server;
import java.io.*;
import client.*;
import junit.framework.TestCase;
public class TestServer extends TestCase {
static int clientCount =0;
public void testMultipleClients() throws Exception {
RepositoryServer server = launchServer();
System.out.println(clientCount);
launchClient();
System.out.println(clientCount);
launchClient();
System.out.println(clientCount);
launchClient();
System.out.println(clientCount);
//wait until everything done.
//isClientCountZero();
Thread.sleep(10000);
server.shutdown();
assertEquals(0, server.state);
}
public static void launchClient() {
//incrementClientCount();
new Thread() {
public void run() {
try {
RepositoryClient.main(new String[]{});
} catch (Exception e) {
System.err.println("Unable to launch test client.");
}
}
}.start();
//decrementClientCount();
}
public static RepositoryServer launchServer() throws Exception {
final RepositoryServer server = ServerLauncher.create();
assertEquals(1, server.state);
new Thread() {
public void run() {
try {
server.process();
} catch (IOException ioe) {
System.err.println("Server completed");
}
}
}.start();
Thread.sleep(2000);
return server;
}
public static synchronized boolean isClientCountZero(){
if (clientCount==0) {
return true;
} else {
return false;
}
}
public static synchronized void decrementClientCount(){
clientCount--;
}
public static synchronized void incrementClientCount(){
clientCount++;
}
}
The code in question is in TestServer.java. When the Thread.sleep() methods are active, the server outputs text as expected. However, when the Thread.sleep() methods are commented out and replaced with the increment, decrement, and clientCount methods, it no longer outputs any text, just 'Server Completed'. What is my wrong with my solution to the posted link?
Thank you
I am working on a project trying to make several people be able to control a robot arm. For this they have to connect to a Java server that then sends the commands to a robot screen for video conferencing.
I am trying to have a thread for each client and then I want to be able to switch between the different clients based on sound, because I want the speaker to be able to control the robot.
The clients all provide positional data and the level of sound taken by the kinect, and sent to the server in the form of a string.
I am having problems with performing the switch. Currently they seem to be switching back and forth and it makes the robot go haywire.
Is there a good way of comparing the threads to each other, find the appropriate one, switch to that, all the while checking the other threads to see if or when they become the most appropriate one? While also checking in case other clients try to connect to the server?
Thank you for your help.
I also include my code in case you want to look through it and get a better idea.
This is the server class:
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Hashtable;
public class MultiThreadedServer implements Runnable {
protected int serverPort = 8888;
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread = null;
protected Thread clientThread = null;
protected Thread threadThread = null;
private Hashtable<Long, WorkerRunnable> Users = new Hashtable<Long, WorkerRunnable>();
private ArrayList<Thread> ClientThreads = new ArrayList<Thread>();
private WorkerRunnable client = null;
private ThreadHandler threadHandler = null;
private int sound_max = 0;
private boolean once = true;
public MultiThreadedServer (int port) {
this.serverPort = port;
}
public void run() {
synchronized(this) {
this.runningThread = Thread.currentThread();
}
openServerSocket();
threadHandler = new ThreadHandler();
while( !isStopped() ) {
Socket clientSocket = null;
try {
System.out.println(InetAddress.getLocalHost());
clientSocket = this.serverSocket.accept(); // Connect to clients
} catch (SocketTimeoutException e) {
} catch (IOException e) {
if( isStopped() ) {
System.out.println("Server Stopped");
return;
}
throw new RuntimeException("Error accepting client connection", e);
}
client = new WorkerRunnable(clientSocket, "Multithreaded Server");//Class does client work
clientThread = new Thread(client); // Make a thread for each client
clientThread.start(); // start thread
threadHandler.setUp(client, clientThread); // Set up the thread handler
if ( once == true) { // make sure the threadHandler thread is only created once
threadThread = new Thread(threadHandler);
threadThread.start();
once = false;
}
}
System.out.println("Server Stopped");
}
/**
* Check if the socket is stopped
* #return true if the socket is stopped
*/
private synchronized boolean isStopped() {
return this.isStopped;
}
/**
* Stop and close the socket
*/
public synchronized void stop() {
this.isStopped = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
/**
* Open server socket
*/
private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort);
} catch (IOException e) {
throw new RuntimeException("Cannot open port 8888", e);
}
}
}
This is the Worker class, that handles the data from the clients:
import gnu.io.NoSuchPortException;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class WorkerRunnable implements Runnable {
protected Socket clientSocket = null;
protected String serverText = null;
private BufferedReader inFromClient;
private DataOutputStream outToClient;
private int[] currentPos = new int[6];
private boolean connected = false;
static TwoWaySerialComm serialCom = null;
static MultiServoState mState;
static int sound_average;
int[] degrees = new int[7];
int count = 0;
public WorkerRunnable(Socket clientSocket, String serverText) {
this.clientSocket = clientSocket;
this.serverText = serverText;
initCurrentPos();
if (serialCom == null) {
serialCom = new TwoWaySerialComm();
}
try {
if (!serialCom.isConnected("COM5")) {
try {
serialCom.connect("COM5");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mState = new MultiServoState(serialCom);
}
} catch (NoSuchPortException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
work();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
}
}
public void work() throws InterruptedException {
try {
InputStream input = clientSocket.getInputStream();
OutputStream output = clientSocket.getOutputStream();
inFromClient = new BufferedReader(new InputStreamReader(input));
outToClient = new DataOutputStream(output);
long time = System.currentTimeMillis();
updateData();
String message = null;
long endTime = System.currentTimeMillis() + 2000;
while ((message = (String) inFromClient.readLine()) != null) {
System.out.println("Message Received: " + message);
parse(message);
sound_average = degrees[6];
//
// Send the positional data to the robot
//
mState.runServo(degrees[0], degrees[1], degrees[2],
degrees[3], degrees[4], degrees[5]);
//
// Send a response information to the client application
//
currentPos[0] = mState.getCurrentPos(0);
currentPos[1] = mState.getCurrentPos(1);
currentPos[2] = mState.getCurrentPos(2);
currentPos[3] = mState.getCurrentPos(3);
currentPos[4] = mState.getCurrentPos(4);
try {
updateData();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Request processed: " + time);
} catch (IOException e) {
// report exception somewhere
e.printStackTrace();
}
}
/**
* Initiate the robot's starting position.
*/
public void initCurrentPos()
{
currentPos[0] = 100;
currentPos[1] = 100;
currentPos[2] = 100;
currentPos[3] = 100;
currentPos[4] = 100;
currentPos[5] = 0;
}
/**
* Send the data to the client
*
* #throws IOException
*/
public void updateData() throws IOException {
String sentence = Integer.toString(currentPos[0]) + ", " +
Integer.toString(currentPos[1]) + ", " +
Integer.toString(currentPos[2]) + ", " +
Integer.toString(currentPos[3]) + ", " +
Integer.toString(currentPos[4]) + "." + "\n";
outToClient.flush();
outToClient.writeBytes(sentence);
}
/**
* Get the clients sound average
* #param message
*/
public int getSoundAverage() {
return sound_average;
}
public void parse(String message) {
if (message != null) {
char c;
StringBuilder sb = new StringBuilder(4);
int j = 0;
boolean help = false;
for (int i = 0; i < message.length(); i++) {
c = message.charAt(i);
if (Character.isDigit(c)) {
sb.append(c);
help = true;
}
if (!Character.isDigit(c) && help == true) {
degrees[j] = Integer.parseInt(sb.toString());
j++;
help = false;
sb.delete(0, sb.length());
}
}
}
System.out.println("Waiting for client message...");
}
/**
* Close all connections
*/
public void close() {
if (connected) {
synchronized (this) {
connected = false;
}
if (outToClient != null) {
try {
outToClient.close();
synchronized (this) {
outToClient = null;
}
} catch (IOException e) {
// there is nothing we can do: ignore it
}
}
if (inFromClient != null) {
try {
inFromClient.close();
synchronized (this) {
inFromClient = null;
}
} catch (IOException e) {
// there is nothing we can do: ignore it
}
}
if (clientSocket != null) {
try {
clientSocket.close();
synchronized (this) {
clientSocket = null;
}
} catch (IOException e) {
// there is nothing we can do: ignore it
}
}
}
}
public void returnThread() {
return;
}
}
The final class is the thread handler where I try to compare sound levels and yield all threads except the loudest one:
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Hashtable;
import com.research.aserver.WorkerRunnable;
public class ThreadHandler implements Runnable {
protected boolean isStopped = false;
protected Thread runningThread = null;
protected Thread clientThread = null;
private Hashtable<Long, WorkerRunnable> Users = new Hashtable<Long, WorkerRunnable>();
private ArrayList<Thread> ClientThreads = new ArrayList<Thread>();
private WorkerRunnable client = null;
private int sound_max = 0;
private int index = 0;
public ThreadHandler() {
}
public void setUp(WorkerRunnable client, Thread clientThread) {
this.client = client;
this.clientThread = clientThread;
Users.put(clientThread.getId(), this.client); // Place clients in a list with its thread ID as key
ClientThreads.add(this.clientThread); // List of client threads
}
#Override
public void run() {
long endTime = System.currentTimeMillis() + 2000; // Help variable to check every 2 sec
while (!Users.isEmpty() && !ClientThreads.isEmpty()) {
for (int i = 0; i < ClientThreads.size(); i++) { // Remove clients and threads if no longer active
if (!ClientThreads.get(i).isAlive()) {
Users.remove(ClientThreads.get(i).getId());
ClientThreads.get(i).interrupt();
ClientThreads.remove(i);
}
}
if(System.currentTimeMillis() >= endTime) { // Do work every 2 sec
for (int i = 0; i < ClientThreads.size(); i++) { // Get the client with the loudest sound
if (sound_max < Users.get(ClientThreads.get(i).getId()).getSoundAverage()) {
sound_max = Users.get(ClientThreads.get(i).getId()).getSoundAverage();
index = i;
}
}
for (int i = 0; i < ClientThreads.size(); i++) { // yield all threads that are not the loudest
if (Users.get(ClientThreads.get(index).getId()) != Users.get(ClientThreads.get(i).getId())){
ClientThreads.get(i).yield();
index = 0;
}
}
endTime = System.currentTimeMillis() + 2000; // update time
}
sound_max = 0;
}
}
}
One idea might be to use a PriorityBlockingQueue and define a quality value for each input, which is then sort by quality automatically inside the list.
Using this your consumer thread can simply fetch the first one in line and process it, knowing that it is the most appropriate one, while the generator threads can simply throw all input in the Queue.
I'm trying to implement WebSockets with a Javascript-based client and a Java-based server. I think I've done all the correct steps, but for an unknown reason, I can't establish the connection with both.
When the server socket receives a connection, it handles to form a websocket-accept response, and it sends back to the client, but the connection in the client socket instantly close, weird that there's no handshake problem.
Does anyone have an idea what might be the problem?
Here's my server code implemented in java:
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import server.message.Message;
import server.message.SpeakMessage;
public class Server implements ConnectionListener {
private static final int PORT = 1509;
private MessageDispatcher dispatcher = new MessageDispatcher();
private List<ConnectionManager> clients = new ArrayList<>();
public void listen() {
try (ServerSocket server = new ServerSocket(PORT)) {
System.out.printf("Listening on port %d...%n", PORT);
while (true) {
System.out.println("Waiting for connection...");
Socket client = server.accept();
System.out.println("Incoming connection - Attempting to establish connection...");
ConnectionManager manager = new ConnectionManager(client, dispatcher, this);
manager.start();
}
} catch (IOException e) {
System.out.println("Unable to start server");
e.printStackTrace();
}
System.exit(0);
}
public void execute() {
try {
while (true) {
if (dispatcher.isEmpty()) {
Thread.sleep(100);
continue;
}
Message msg = dispatcher.read();
if (msg instanceof SpeakMessage)
broadcast(MessageEncoder.spoke(((SpeakMessage) msg).getText()));
}
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
public static void main(String[] args) {
final Server server = new Server();
new Thread(new Runnable() {
#Override
public void run() {
server.listen();
}
}).start();
server.execute();
}
public synchronized void broadcast(byte[] message) {
for (ConnectionManager client : clients) {
client.send(message);
}
}
#Override
public synchronized void clientConnected(ConnectionManager who) {
clients.add(who);
System.out.println("Connected client " + clients.size());
}
#Override
public synchronized void clientDisconnected(ConnectionManager who) {
clients.remove(who);
}
}
Heres subclass ConnectionManager of server:
package server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.security.MessageDigest;
import java.util.Properties;
import server.message.HandshakeMessage;
import server.message.Message;
public class ConnectionManager {
private static final int CLIENT_VERSION = 1;
private Socket socket;
private MessageDecoder decoder = new MessageDecoder();
private MessageDispatcher dispatcher;
private ConnectionListener listener;
public ConnectionManager(Socket connection, MessageDispatcher dispatcher, ConnectionListener listener) {
socket = connection;
this.dispatcher = dispatcher;
this.listener = listener;
}
public void start() {
Thread t = new Thread(new ChannelReader());
t.setName("Client thread");
t.setDaemon(true);
t.start();
}
public void send(byte[] data) {
if (socket == null)
return;
try {
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.write(data);
dos.flush();
} catch (IOException e) {
disconnect("Client closed the connection");
}
}
private class ChannelReader implements Runnable {
private boolean accepted = false;
private String ret = null;
#Override
public void run() {
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
while (socket != null && socket.isConnected()) {
int len = in.readShort();
if (len < 0) {
disconnect("Invalid message length.");
}
String s;
readLine(in);
Properties props = new Properties();
while((s=readLine(in)) != null && !s.equals("")) {
String[] q = s.split(": ");
props.put(q[0], q[1]);
}
if(props.get("Upgrade").equals("websocket") && props.get("Sec-WebSocket-Version").equals("13")) { // check if is websocket 8
String key = (String) props.get("Sec-WebSocket-Key");
String r = key + "" + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // magic key
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.reset();
md.update(r.getBytes());
byte[] sha1hash = md.digest();
String returnBase = base64(sha1hash);
ret = "HTTP/1.1 101 Switching Protocols\r\n";
ret+="Upgrade: websocket\r\n";
ret+="Connection: Upgrade\r\n";
ret+="Sec-WebSocket-Accept: "+returnBase;
} else {
disconnect("Client got wrong version of websocket");
}
Message msg = decoder.decode((String) props.get("Sec-WebSocket-Protocol"));
if (!accepted) {
doHandshake(msg);
} else if (dispatcher != null) {
dispatcher.dispatch(msg);
}
}
} catch (Exception e) {
disconnect(e.getMessage());
e.printStackTrace();
}
}
private void doHandshake(Message msg) {
if (!(msg instanceof HandshakeMessage)) {
disconnect("Missing handshake message");
return;
}
HandshakeMessage handshake = (HandshakeMessage) msg;
if (handshake.getVersion() != CLIENT_VERSION) {
disconnect("Client failed in handshake.");
return;
}
send(ret.getBytes());
accepted = true;
listener.clientConnected(ConnectionManager.this);
}
private String base64(byte[] input) throws ClassNotFoundException,
SecurityException, NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> c = Class.forName("sun.misc.BASE64Encoder");
java.lang.reflect.Method m = c.getMethod("encode", new Class<?>[]{byte[].class});
String s = (String) m.invoke(c.newInstance(), input);
return s;
}
private String readLine(InputStream in) {
try{
String line = "";
int pread;
int read = 0;
while(true) {
pread = read;
read = in.read();
if(read!=13&&read!=10)
line += (char) read;
if(pread==13&&read==10) break;
}
return line;
}catch(IOException ex){
}
return null;
}
}
public synchronized void disconnect(String message) {
System.err.println(message);
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
}
}
socket = null;
listener.clientDisconnected(ConnectionManager.this);
}
}
And the MessageDispatcher:
package server;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingDeque;
import server.message.Message;
public class MessageDispatcher {
Queue<Message> messageQueue = new LinkedBlockingDeque<>();
public void dispatch(Message message) {
messageQueue.offer(message);
}
public Message read() {
return messageQueue.poll();
}
public boolean isEmpty() {
return messageQueue.isEmpty();
}
}
And heres my client code implemented in javascript:
var canvas, // Canvas DOM element
ctx, // Canvas rendering context
socket; // Socket connection
function init() {
// Initialise the canvas
canvas = document.getElementById("gameCanvas");
ctx = canvas.getContext("2d");
// Maximise the canvas
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Initialise socket connection
if (window.WebSocket) {
socket = new WebSocket("ws://localhost:1509/", ["1", "YURI"]);
socket.onopen = onSocketConnected();
socket.onclose = onSocketDisconnect();
socket.onmessage = onSocketMessage();
socket.onerror = onSocketError();
} else {
alert("The browser does not support websocket.");
}
};
// Socket message
function onSocketMessage(message) {
console.log('Message: ' + message.data);
};
// Socket error
function onSocketError(error) {
console.log('Error: ' + error.data);
};
// Socket connected
function onSocketConnected() {
console.log("Connected to socket server");
};
// Socket disconnected
function onSocketDisconnect() {
console.log("Disconnected from socket server");
};
I think, it is because you are using the Socket Package on the Java Server Side and the WebSocket API on the Client Side. Your idea is really good but the wrong technology.
Keep the WebSocket on the Client Side (Javascript) becaue you don't have lots of other possibilities, but try JWebSocket on the Server side (Java). In Fact WebSocket is using TCP/IP but its own communication protocol over TCP/IP. The Java Socket Package is purely TCP/IP. Re-write your server with JWebSocket, all details about JWebSocket can be found at:
http://jwebsocket.org/.
I hope my answer will help you.
you must specify end of return packet with "\r\n\r\n"
ret = "HTTP/1.1 101 Switching Protocols\r\n";
ret+="Upgrade: websocket\r\n";
ret+="Connection: Upgrade\r\n";
ret+="Sec-WebSocket-Accept: "+returnBase + "\r\n\r\n";
and for create accept key i use
public class WSKeyGenerator {
private final static String MAGIC_KEY =
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
public static String getKey(String strWebSocketKey) throws
NoSuchAlgorithmException {
strWebSocketKey += MAGIC_KEY;
MessageDigest shaMD = MessageDigest.getInstance("SHA-1");
shaMD.reset();
shaMD.update(strWebSocketKey.getBytes());
byte messageDigest[] = shaMD.digest();
BASE64Encoder b64 = new BASE64Encoder();
return b64.encode(messageDigest);
}
}
I recommend that use the http://websocket.org/echo.html to check the server's websocket functionality
I have Vector of threads, and i wanna check all items in this vector. Everyone item is connection of user to server. I wanna "clean" all dead connections.
I can't find where I'm wrong.
Here is it my code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package server;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.ServerCore.Clients;
/**
*
* #author pisio
*/
public class GrimReaper extends Thread {
private int timeout = LoadSettings.Init().getConfigInt("grimreaper") * 1000; // 1000 ms = 1 sec
public GrimReaper() {
super();
}
public void cleanUserThreads() {
Vector users = ServerCore.users;
if (users.size() < 1) {
return;
}
Iterator iteratr = users.iterator();
while (iteratr.hasNext()) {
Clients user = (Clients) iteratr.next();
System.out.println(user.isAlive());
if (user.getClient().isClosed()) {
user.interrupt();
if (user.isInterrupted()) {
System.out.println("Beshe kiknat");
}
iteratr.remove();
// if (PublicVaribles.Init().systemLevelMesseging() == 2) {
System.out.println("+\t Kicked user ");
// }
}//if is dead
}//while
}//cleanUserThreads;
#Override
public void run() {
try {
while (ServerCore.getServerRunning()) {
cleanUserThreads();
sleep(timeout);
System.out.println("nani na shinigami");
}
} catch (InterruptedException ex) {
Logger.getLogger(GrimReaper.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
package server;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import server.DB.DataBase;
public class ServerCore extends Thread {
private static ServerCore sc = null;
private int port = LoadSettings.Init().getConfigInt("port");
private int max_connections = LoadSettings.Init().getConfigInt("max_connections");
private String ipServer = LoadSettings.Init().getConfig("ipServer");
private ServerSocket socket;
private static boolean serverRuning = false;
public static Vector users = new Vector();
public GrimReaper shinigami = new GrimReaper();// Shinigami from Japanice is Grim Reaper!
private ServerCore() {
}
#Override
public void run() {
shinigami.start();
try {
socket = new ServerSocket(port, max_connections);
System.out.println("+++\t Server was started at address:" + socket.getLocalSocketAddress() + " with posible max users " + max_connections);
serverRuning = true;
while (serverRuning) {
Socket client = socket.accept();
shinigami.cleanUserThreads();
if (users.size() < max_connections) {
Clients cls = new Clients(client);
cls.start();
users.add(cls);
System.out.println("++\tClient was connected:" + client.toString());
} else {
Clients cls = new Clients(client);
cls.start();
cls.getOutput().println("sorry_no_avable_slot");
cls.getOutput().flush();
cls.interrupt();
}
}
} catch (IOException ex) {
// Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
}
//run method
public void sendUserMsg() {
Scanner input = PublicVaribles.Init().inputKeyBord();
System.out.print("Enter UserID/user connection port:");
int userID = input.nextInt();
Iterator iterator = users.iterator();
while (iterator.hasNext()) {
Clients cls = (Clients) iterator.next();
/// System.out.println("Passed user:" + cls.getUserId());
if (cls.getUserId() == userID) {
System.out.print("\nEnter msg:");
String str = input.next();
cls.getOutput().println(str);
System.out.println("+\t" + cls.getUserId() + " get msg :" + str);
}
}
}
//SendUserMsg
public void stopServer() {
statusServer();
serverRuning = false;
try {
socket.close();
} catch (IOException ex) {
Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("+++\t SERVER WAS STOPED !");
}
//Stop server
public void statusServer() {
if (serverRuning) {
System.out.println("+++\t Server running at port:" + port + " with connected users :" + users.size() + "/" + max_connections);
} else {
System.out.println("+++\t Server IS NOT RUNNING!");
}
}
//Status server
public static boolean getServerRunning() {
// function for GrimReaper .... R.I.P :D
return ServerCore.serverRuning;
}
public static ServerCore Init() {
if (ServerCore.sc == null) {
ServerCore.sc = new ServerCore();
}
return ServerCore.sc;
}
// SingleTon
public class Clients extends Thread {
private Socket client;
private int userID;
private Scanner input;
private PrintWriter output;
public Clients(Socket socket) {
client = socket;
userID = socket.getPort();
try {
input = new Scanner(client.getInputStream());
output = new PrintWriter(client.getOutputStream(), true);
} catch (IOException ioEx) {
System.out.println(ioEx.toString());
}
}
public int getUserId() {
return userID;
}
public Scanner getInput() {
return input;
}
public PrintWriter getOutput() {
return output;
}
public Socket getClient() {
return client;
}
}//Clients Class
}
Note: I'm assuming Clients extends Thread.
It looks like you might be using interrupt() incorrectly. After calling user.interrupt(), it's up to that thread to check that it has been interrupted by calling Thread.interrupted() and terminate itself if true. Here's an extremely basic example:
class Clients extends Thread {
#Override
public void run() {
while (!Thread.interrupted()) {
//do work
}
//thread has been interrupted and quits
}
}