I have a piece of code that connects a client to my server. However, every time I connect a client to the server it controls the same player instead of creating a new player. I think it is because I am not creating a new thread for every new client. If someone could show me how to create a new thread for every client that joins using the code I have already written.
import java.net.*;
import java.io.*;
public class Client extends PlayGame
{
public static void main(String [] args)
{
//String serverName = args[0];
//int port = Integer.parseInt(args[1]);
String serverName = "localhost";
int port = 40004;
//while (true ) {
try
{
System.out.println("Connecting to " + serverName + " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
//out.writeUTF("Hello from " + client.getLocalSocketAddress());
//DataInputStream in = new DataInputStream(inFromServer);
//System.out.println("Server says " + in.readUTF());
PlayGame game = new PlayGame();
//System.out.println("Do you want to load a specitic map?");
//System.out.println("Press enter for default map");
//game.selectMap(game.readUserInput());
//System.out.println("You may now use MOVE, LOOK, QUIT and any other legal commands");
String input = game.readUserInput();
while (input != "quit") {
out.writeUTF( input );
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("Server Response:\n" + in.readUTF());
input = game.readUserInput();
}
//game.update();
//client.close();
}catch(IOException e)
{
e.printStackTrace();
}
//}
}
}
Server class and ClientThread subclass
import java.net.*;
import java.util.Random;
import java.io.*;
public class Server implements IGameLogic
{
private ServerSocket serverSocket;
private Map map = null;
private int[] playerPosition;
private int collectedGold;
private boolean active;
public Server(int port) throws IOException
{
serverSocket = new ServerSocket(port);
//serverSocket.setSoTimeout(10000);
}
public void startServer()
{
map = new Map();
setMap(new File("example_map.txt"));
System.out.println("Game Started - Map Initialized");
while(true)
{
try
{
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
ClientThread ct = new ClientThread(server, this );
ct.start();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public void setMap(File file) {
map.readMap(file);
playerPosition = initiatePlayer();
active = true;
}
/**
* Prints how much gold is still required to win!
*/
public synchronized String hello() {
return "GOLD: " + (map.getWin() - collectedGold);
}
/**
* By proving a character direction from the set of {N,S,E,W} the gamelogic
* checks if this location can be visited by the player.
* If it is true, the player is moved to the new location.
* #return If the move was executed Success is returned. If the move could not execute Fail is returned.
*/
public synchronized String move(char direction) {
int[] newPosition = playerPosition.clone();
switch (direction){
case 'N':
newPosition[0] -=1;
break;
case 'E':
newPosition[1] +=1;
break;
case 'S':
newPosition[0] +=1;
break;
case 'W':
newPosition[1] -=1;
break;
default:
break;
}
if(map.lookAtTile(newPosition[0], newPosition[1]) != '#'){
playerPosition = newPosition;
if (checkWin())
quitGame();
return "SUCCESS";
} else {
return "FAIL";
}
}
public synchronized String pickup() {
if (map.lookAtTile(playerPosition[0], playerPosition[1]) == 'G') {
collectedGold++;
map.replaceTile(playerPosition[0], playerPosition[1], '.');
return "SUCCESS, GOLD COINS: " + collectedGold;
}
return "FAIL" + "\n" + "There is nothing to pick up...";
}
/**
* The method shows the dungeon around the player location
*/
public synchronized String look() {
String output = "";
char [][] lookReply = map.lookWindow(playerPosition[0], playerPosition[1], 5);
lookReply[2][2] = 'P';
for (int i=0;i<lookReply.length;i++){
for (int j=0;j<lookReply[0].length;j++){
output += lookReply[j][i];
}
output += "\n";
}
return output;
}
public boolean gameRunning(){
return active;
}
/**
* Quits the game when called
*/
public void quitGame() {
System.out.println("The game will now exit");
active = false;
}
/**
* finds a random position for the player in the map.
* #return Return null; if no position is found or a position vector [y,x]
*/
private int[] initiatePlayer() {
int[] pos = new int[2];
Random rand = new Random();
pos[0]=rand.nextInt(map.getMapHeight());
pos[1]=rand.nextInt(map.getMapWidth());
int counter = 1;
while (map.lookAtTile(pos[0], pos[1]) == '#' && counter < map.getMapHeight() * map.getMapWidth()) {
pos[1]= (int) ( counter * Math.cos(counter));
pos[0]=(int) ( counter * Math.sin(counter));
counter++;
}
return (map.lookAtTile(pos[0], pos[1]) == '#') ? null : pos;
}
/**
* checks if the player collected all GOLD and is on the exit tile
* #return True if all conditions are met, false otherwise
*/
protected boolean checkWin() {
if (collectedGold >= map.getWin() &&
map.lookAtTile(playerPosition[0], playerPosition[1]) == 'E') {
System.out.println("Congratulations!!! \n You have escaped the Dungeon of Dooom!!!!!! \n"
+ "Thank you for playing!");
return true;
}
return false;
}
public static void main(String [] args)
{
//int port = Integer.parseInt(args[0]);
int port = 40004;
try
{
//Thread t = new Server(port);
//t.start();
Server s = new Server(port);
s.startServer();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
class ClientThread extends Thread {
//private byte[] data = new byte[255];
//private Socket socket;
private Socket _socket;
private Server _server;
public ClientThread(Socket socket, Server s) {
// for (int i = 0; i < data.length; i++)
// data[i] = (byte) i;
this._socket = socket;
this._server = s;
}
public void run() {
/* try {
OutputStream out = new BufferedOutputStream(socket.getOutputStream());
while (!socket.isClosed()) {
out.write(data);
}
socket.close();
} catch (Exception e) {
} */
try{
System.out.println("Just connected to " + _socket.getRemoteSocketAddress());
while ( _server.gameRunning() ) {
DataInputStream in = new DataInputStream(_socket.getInputStream());
// System.out.println(in.readUTF());
String input = in.readUTF();
System.out.println("Received from client: " + input );
DataOutputStream out = new DataOutputStream(_socket.getOutputStream());
//out.("Thank you for connecting to " + server.getLocalSocketAddress() + "\nGoodbye!");
if ( input.equals("LOOK") ) {
//String output = look();
System.out.println("LOOK" );
out.writeUTF( _server.look() );
} else if ( input.equals("HELLO") ) {
System.out.println("HELLO");
out.writeUTF( _server.hello() );
} else if ( input.equals("PICKUP") ) {
System.out.println("PICKUP");
out.writeUTF( _server.pickup() );
} else if ( input.equals("QUIT") ) {
System.out.println("QUIT");
_server.quitGame();
out.writeUTF( "The game has completed" );
} else if ( input.equals("MOVE N") ) {
System.out.println("MOVE N");
out.writeUTF( _server.move('N') );
} else if ( input.equals("MOVE E") ) {
System.out.println("MOVE E");
out.writeUTF( _server.move('E') );
} else if ( input.equals("MOVE S") ) {
System.out.println("MOVE S");
out.writeUTF( _server.move('S') );
} else if ( input.equals("MOVE W") ) {
System.out.println("MOVE W");
out.writeUTF( _server.move('W') );
} else {
out.writeUTF("Invalid Command");
}
}
}catch(IOException e){
//ioex.printStackTrace();
e.printStackTrace();
//break;
}
//DataOutputStream out = new DataOutputStream(server.getOutputStream());
//out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress() + "\nGoodbye!");
//server.close();
}
}
Related
Screenshot of program running (top is server, bottom right is first client, bottom left is second client):
Screenshot of program running
The problem with the screenshot above is that the message that appears on the bottom left window User name: something has been added to position 0 in the namesList array should instead be User name: something has been added to position 1 in the namesList array The reason the position needs to be 1 instead of 0 is because the first name should be stored in the first position, and the second name should be stored in the second position (to make the list of names actually store all of the names)
The issue is making the namesList array and position sync.
EDIT: it seems that threads[i] has global accessibility, is it possible that I should make an arraylist of file names with objects to somehow store the names of the connected clients instead of a regular string array to store them?
What changes can I make to the following code that would make the array sync and accessible to all clients?
ChatThreads.java code:
import java.io.*;
import java.net.*;
import java.util.*;
class ClientThreads extends Thread
{
public String name1 = "";
private String clientName = null;
private DataInputStream is = null;
private PrintStream os = null;
private Socket clientSocket = null;
private final ClientThreads[] threads;
private int maxClientsCount;
public static String[] namesList = new String[4];
public int iteration = 0;
public static String[] responses = new String[50];
public int responseCount = 0;
public ClientThreads(Socket clientSocket, ClientThreads[] threads, String name)
{
this.clientSocket = clientSocket;
this.threads = threads;
maxClientsCount = threads.length;
this.name1 = name;
}
#SuppressWarnings("deprecation")
public void run()
{
int maxClientsCount = this.maxClientsCount;
ClientThreads[] threads = this.threads;
for(int i = 0; i < namesList.length; i++)
{
namesList[i] = "";
}
for(int j = 0; j < responses.length; j++)
{
responses[j] = "";
}
try
{
is = new DataInputStream(clientSocket.getInputStream());
os = new PrintStream(clientSocket.getOutputStream());
String name;
String firstName;
while (true)
{
os.println("What is your name?");
name = is.readLine().trim();
break;
}
synchronized (this)
{
for (int i = 0; i < maxClientsCount; i++)
{
if (threads[i] != null && threads[i] == this)
{
clientName = "#" + name;
break;
}
}
for (int i = 0; i < maxClientsCount; i++)
{
if (threads[i] != null)
{
threads[i].os.println(name + " has connected.");
os.println("Enter an option: 'm' = message, 'f' = file request, 'x' = exit\n");
}
}
}
while (true)
{
String line = is.readLine();
if (line.startsWith("/quit"))
{
break;
}
else
{
//os.println("Enter an option: 'm' = message, 'f' = file request, 'x' = exit\n");
}
if(line.equals("x") || line.equals("X"))
{
os.println("x");
System.exit(0);
}
if(line.equals("m") || line.equals("M"))
{
os.println("Enter your message: ");
}
if(line.equals("f") || line.equals("F"))
{
os.println("Who owns the file?");
boolean keep = true;
while (keep == true)
{
String fileOwner = is.readLine();
if(fileOwner !=null && !fileOwner.isEmpty())
{
responses[responseCount] = fileOwner + "`owns a file";
responseCount++;
os.println(fileOwner);
namesList[iteration] = fileOwner;
System.out.println("User named: " + fileOwner + " has been added to position " + iteration + " in the namesList array.");
iteration++;
keep = false;
os.println("Which file do you want?");
boolean keep2 = true;
while(keep2==true)
{
String filename = is.readLine();
if(filename !=null && !filename.isEmpty())
{
// os.println(filename);
keep2 = false;
os.println("Enter an option: 'm' = message, 'f' = file request, 'x' = exit\n");
}
}
}
}
}
else
{
synchronized (this)
{
for (int i = 0; i < maxClientsCount; i++)
{
if (!line.equals("x") && !line.equals("X") && !line.equals("f") && !line.equals("F") && !line.equals("m") && !line.equals("M") && threads[i] != null && threads[i].clientName != null && !threads[i].clientName.equals("m") && !threads[i].clientName.equals("M"))
{
threads[i].os.println(name + ": " + line + "\n");
this.os.println("Enter an option: 'm' = message, 'f' = file request, 'x' = exit\n");
}
}
}
}
}
synchronized (this)
{
for (int i = 0; i < maxClientsCount; i++)
{
if (threads[i] != null && threads[i] != this && threads[i].clientName != null)
{
threads[i].os.println(name + "has disconnected.");
}
}
}
synchronized (this)
{
for (int i = 0; i < maxClientsCount; i++)
{
if (threads[i] == this)
{
threads[i] = null;
}
}
}
is.close();
os.close();
clientSocket.close();
}
catch (IOException e)
{
}
}
}
ChatClient.java code:
import java.io.*;
import java.net.*;
public class ChatClient implements Runnable
{
private static Socket clientSocket = null;
private static PrintStream os = null;
private static DataInputStream is = null;
private static BufferedReader inputLine = null;
private static boolean closed = false;
public static String[] namesList = new String[4];
public int iteration = 0;
public static String[] responses = new String[50];
public int responseCount = 0;
public static void main(String[] args)
{
for(int i = 0; i < namesList.length; i++)
{
namesList[i] = "";
}
for(int j = 0; j < responses.length; j++)
{
responses[j] = "";
}
int portNumber = Integer.valueOf(args[3]);
String host = "localhost";
int filePort = Integer.valueOf(args[1]);
try
{
clientSocket = new Socket(host, portNumber);
inputLine = new BufferedReader(new InputStreamReader(System.in));
os = new PrintStream(clientSocket.getOutputStream());
is = new DataInputStream(clientSocket.getInputStream());
}
catch (UnknownHostException e)
{
System.err.println("Don't know about host " + host);
} catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to the host "
+ host);
}
if (clientSocket != null && os != null && is != null)
{
try
{
new Thread(new ChatClient()).start();
while (!closed)
{
os.println(inputLine.readLine() );
}
os.close();
is.close();
clientSocket.close();
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}
#SuppressWarnings("deprecation")
public void run()
{
String responseLine = "";
try
{
while ((responseLine = is.readLine()) != null)
{
if(responseLine.equals("x") || responseLine.equals("X"))
{
System.exit(0);
}
if(responseLine.equals("Who owns the file?") && !responseLine.isEmpty() && responseLine != null)
{
responseCount++;
System.out.println(responseLine);
responses[responseCount] = "234782375920192831";
}
if(responseLine.equals("Which file do you want?"))
{
responseCount++;
System.out.println(responseLine);
responses[responseCount] = responseLine;
}
if(responseLine.equals("What is your name?"))
{
responseCount++;
System.out.println(responseLine);
responses[responseCount] = responseLine;
}
if(responseLine.equals("m") || responseLine.equals("M"))
{
responseCount++;
System.out.println("Enter your message: ");
responses[responseCount] = responseLine;
}
if(responseLine.equals("Enter an option: 'm' = message, 'f' = file request, 'x' = exit\n"))
{
responseCount++;
System.out.println(responseLine);
responses[responseCount] = responseLine;
}
if(responseLine != null && !responseLine.isEmpty() && !responseLine.equals("What is your name?") && !responseLine.equals("Enter an option: 'm' = message, 'f' = file request, 'x' = exit\n") && !responseLine.equals("Who owns the file?") && !responseLine.equals("Which file do you want?"))
{
responseCount++;
if(responses[responseCount-1].equals("234782375920192831"))
{
namesList[iteration] = responseLine;
System.out.println("User named: " + responseLine + " has been added to position " + iteration + " in the namesList array." );
iteration++;
}
else
{
System.out.println(responseLine);
responses[responseCount] = responseLine;
}
}
}
closed = true;
}
catch (IOException e)
{
System.err.println("IOException: " + e);
}
}
}
ChatServer.java code
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer
{
public static ServerSocket serverSocket = null;
public static Socket clientSocket = null;
public static final int maxClientsCount = 10;
public static final ClientThreads[] threads = new ClientThreads[maxClientsCount];
public static void main(String args[])
{
if(args.length <3)
{
int portNumber = Integer.valueOf(args[1]).intValue();
System.out.println("waiting for connections on port " + portNumber + " ...\n ");
}
try
{
int portNumber1 = Integer.valueOf(args[1]).intValue();
serverSocket = new ServerSocket(portNumber1);
}
catch (IOException e)
{
System.out.println(e);
}
while (true)
{
try
{
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++)
{
if (threads[i] == null)
{
String name = "";
(threads[i] = new ClientThreads(clientSocket, threads, name)).start();
break;
}
}
if (i == maxClientsCount)
{
PrintStream os = new PrintStream(clientSocket.getOutputStream());
os.println("Server too busy. Try later.");
os.close();
clientSocket.close();
}
}
catch (IOException e)
{
System.out.println(e);
}
}
}
}
ServerThread.java code:
import java.io.DataInputStream;
import java.io.PrintStream;
import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;
public class ServerThread
{
private static ServerSocket serverSocket = null;
private static Socket clientSocket = null;
private static final int maxClientsCount = 10;
private static final ClientThreads[] threads = new ClientThreads[maxClientsCount];
public static void main(String args[])
{
int portNumber = Integer.valueOf(args[1]).intValue();
if(args.length <3)
{
System.out.println("waiting for conennections on port" + portNumber + " ...\n ");
}
try
{
serverSocket = new ServerSocket(portNumber);
}
catch (IOException e)
{
System.out.println(e);
}
while (true)
{
try
{
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++)
{
if (threads[i] == null)
{
String name = "";
(threads[i] = new ClientThreads(clientSocket, threads, name)).start();
break;
}
}
if (i == maxClientsCount)
{
PrintStream os = new PrintStream(clientSocket.getOutputStream());
os.println("Server too busy. Try later.");
os.close();
clientSocket.close();
}
}
catch (IOException e)
{
System.out.println(e);
}
}
}
}
My question is: How would I make the namesList array the same across multiple clients with the position?
Using code examples from stockoverflow I made a class to receive data over TCP/IP.
Class code below. It is working OK and I do receive data from other PC.
recPositions Map is build correctly. After transmission is finished I can display all data I received using getRecPositions()
This thread is started in other class that build simple HMI screen.
Thread runs and display data received from other PC.
Problem is I would like to access same data in MainWindow class (HMI)
but it always show that nothing was received.
Class MainWindow below (not all of it since there is lots of useless pushbuttons and so on)
At the very bottom I have pushbutton that should display how many positions were recorded (elements in Map) but it always show 0.
Code snippet from push button update.
System.out.println(dataServer.getRecPositions().size())
So at some point I am doing something wrong.
Thread starts and runs and I can see incoming positions. At some point after I received "EOT" I display received positions stored in Map. But when I tried to display the size of Map in main window it always show 0.
/*
* Simple data server for receiving string data from IIWA robot
*/
public class SimpleDataServer implements Runnable {
Map<Integer, String> recPositions = new HashMap<>();
Server1Connection oneconnection;
ServerSocket echoServer = null;
Socket clientSocket = null;
int port;
boolean reset = false;
public SimpleDataServer( int port ) {
this.port = port;
}
public void stopServer() {
System.out.println( "Simple data server stopped" );
}
public void startServer() {
// Try to open a server socket on the given port
// Note that we can't choose a port less than 1024 if we are not
// privileged users (root)
try {
echoServer = new ServerSocket(port);
}
catch (IOException e) {
System.out.println(e);
}
System.out.println( "Waiting for connections. Only one connection is allowed." );
// Create a socket object from the ServerSocket to listen and accept connections.
// Use Server1Connection to process the connection.
while ( true ) {
try {
clientSocket = echoServer.accept();
oneconnection = new Server1Connection(clientSocket, this);
oneconnection.run();
if(isReset()) {
setReset(false);
System.out.println("Recording finished");
System.out.println("DEBUG:" + this.getRecPositions().size() + " positions recorded: " + this.getRecPositions());
}
}
catch (IOException e) {
System.out.println(e);
}
}
}
#Override
public void run() {
int port = this.port;
SimpleDataServer server = new SimpleDataServer( port );
server.startServer();
}
public Map<Integer, String> getRecPositions() {
return recPositions;
}
public void setRecPositions(Map<Integer, String> recPositions) {
this.recPositions = recPositions;
}
public boolean isReset() {
return reset;
}
public void setReset(boolean reset) {
this.reset = reset;
}
}
class Server1Connection {
BufferedReader is;
PrintStream os;
Socket clientSocket;
SimpleDataServer server;
public Server1Connection(Socket clientSocket, SimpleDataServer server) {
this.clientSocket = clientSocket;
this.server = server;
System.out.println( "Connection established with: " + clientSocket );
try {
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
os = new PrintStream(clientSocket.getOutputStream());
} catch (IOException e) {
System.out.println(e);
}
}
public Map<Integer, String> getPositions() {
return server.getRecPositions();
}
public void run() {
String line; //whole line recevied
String segment = null; //single segment from line using comma delimiter
List<String> stringsList;
try {
boolean serverStop = false;
//server runs here
while (true)
{
line = is.readLine();
System.out.println( "DEBUG Server Received: " + line );
//check is string is not empty
if (line.equals(null)) {
System.err.println("Empty String received");
break;
}
stringsList = new ArrayList<String>(Arrays.asList(line.split(";")));
if (!stringsList.isEmpty()) {
stringsList.set(0, stringsList.get(0).replaceAll("\\s+",""));
stringsList.set((stringsList.size()-1), stringsList.get(stringsList.size()-1).replaceAll("\\s+",""));
String lastSegment = stringsList.get((stringsList.size()-1));
if (lastSegment.equals("ETX") || lastSegment.equals("EOT")) {
switch (stringsList.get(0)) {
case "MSG":
stringsList.remove(0);
stringsList.remove(stringsList.size()-1);
System.out.println("Message: " + stringsList.toString());
break;
case "POS":
// for (String blah : stringsList) {
// System.out.println("DEBUG" + blah);
// }
iiwaPosfromString iiwaPos = new iiwaPosfromString(stringsList.get(1), stringsList.get(2));
System.out.println("DEBUG Position number: " + iiwaPos.posNum + " ; " + iiwaPos.toString());
if (iiwaPos.getPosNum() > 0) {
server.getRecPositions().put(iiwaPos.getPosNum(), iiwaPos.toString());
}
break;
case "EOT":
case "EXT":
//ignore handled later
break;
default:
System.err.println("Ausgebombt!");
break;
}
}
//ETX End Of Text - dump data to screen - close current connection
if(lastSegment.equals("ETX")) {
System.out.println("End of Text received");
break;
}
//EOT End Of Transmission - shuts down server
if(lastSegment.equals("EOT")) {
System.out.println("End of Transmission received");
serverStop = true;
server.setReset(true);
break;
}
System.err.println("No correct end string!");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
} else {
System.out.println("Empty String received");
break;
}
}
System.out.println( "Connection closed." );
is.close();
os.close();
clientSocket.close();
if ( serverStop ) server.stopServer();
} catch (IOException e) {
System.out.println(e);
}
}
public class iiwaPosfromString {
private double posX;
private double posY;
private double posZ;
private double posA;
private double posB;
private double posC;
private int posNum;
public iiwaPosfromString(String posNum, String posString) {
List <String>stringsList = new ArrayList<String>(Arrays.asList(posString.split(" ")));
for (int i = 0; i < stringsList.size(); i++) {
String newElement = stringsList.get(i);
newElement = newElement.replaceAll("[^\\d.]", "");
stringsList.set(i, newElement);
}
this.setPosNum(Integer.parseInt(posNum));
this.setPosX(Double.parseDouble(stringsList.get(1)));
this.setPosY(Double.parseDouble(stringsList.get(2)));
this.setPosZ(Double.parseDouble(stringsList.get(3)));
//this is stupid and don't do that
//from right to left, string to double, change radians to degrees, format to two decimals(string), string to double again
this.setPosA(Double.parseDouble(String.format("%.2f",(Math.toDegrees(Double.parseDouble(stringsList.get(4)))))));
this.setPosB(Double.parseDouble(String.format("%.2f",(Math.toDegrees(Double.parseDouble(stringsList.get(4)))))));
this.setPosC(Double.parseDouble(String.format("%.2f",(Math.toDegrees(Double.parseDouble(stringsList.get(4)))))));
}
public double getPosX() {
return posX;
}
public void setPosX(double posX) {
this.posX = posX;
}
public double getPosY() {
return posY;
}
public void setPosY(double posY) {
this.posY = posY;
}
public double getPosZ() {
return posZ;
}
public void setPosZ(double posZ) {
this.posZ = posZ;
}
public double getPosA() {
return posA;
}
public void setPosA(double posA) {
this.posA = posA;
}
public double getPosB() {
return posB;
}
public void setPosB(double posB) {
this.posB = posB;
}
public double getPosC() {
return posC;
}
public void setPosC(double posC) {
this.posC = posC;
}
#Override
public String toString() {
return "<" +
"X: " + getPosX() + ", " +
"Y: " + getPosY() + ", " +
"Z: " + getPosZ() + ", " +
"A: " + getPosA() + ", " +
"B: " + getPosB() + ", " +
"C: " + getPosC() +
">";
}
public int getPosNum() {
return posNum;
}
public void setPosNum(int posNum) {
this.posNum = posNum;
}
}
}
public class MainWindow {
private Thread dataServerThread;
private SimpleDataServer dataServer;
private XmlParserGlobalVarsRD globalVarPLC, globalVarKRC;
private JFrame frame;
private JTextField simpleWorkingDirStiffness;
private JTextField simpleWorkingDirAdditionalForce;
private JTextField simpleTravelDistance;
private JTextField simpleTravelVelocity;
private JTextField simpleTotalTime;
private JTextField simpleTheoreticalDepth;
private JTextField simpleZProgress;
private JComboBox oscillationMode;
/**
* Launch the application.
*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Throwable e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainWindow window = new MainWindow();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainWindow() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
final JCheckBox emptyScanCycle = new JCheckBox("VRSI Scan Cycle Plain Fasteners");
//set data server thread and start it
dataServer = new SimpleDataServer(30008);
dataServerThread = new Thread(dataServer);
dataServerThread.setDaemon(true);
dataServerThread.start();
...
JButton pbUpdate = new JButton("UPDATE");
pbUpdate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println(dataServer.getRecPositions().size())
}
});
pbUpdate.setBounds(210, 176, 90, 28);
frame.getContentPane().add(pbUpdate);
}
I believe the issue is in your SimpleDataServer.run method. You are creating a separate instance of SimpleDataServer from WITHIN your SimpleDataServer instance. Therefore, all of the communication is taking place in an object that your MainWindow has no direct reference to. I believe your SimpleDataServer.run method should look like this:
#Override
public void run() {
this.startServer();
}
I am trying to make a video streaming application between pc and android device. so I am getting this error "SocketTimeoutException"
private class ChatOperator extends AsyncTask<Void, Void, Void> {
DatagramPacket rcvdp;
DatagramSocket RTPsocket;
int RTP_RCV_PORT = 25000;
Timer timer;
byte[] buf;
final static int INIT = 0;
final static int READY = 1;
final static int PLAYING = 2;
int state;
Socket RTSPsocket;
BufferedReader RTSPBufferedReader;
BufferedWriter RTSPBufferedWriter;
String VideoFileName;
int RTSPSeqNb = 0;
int RTSPid = 0;
final static String CRLF = "\r\n";
int MJPEG_TYPE = 26;
#Override
protected Void doInBackground(Void... params) {
buf = new byte[15000];
int RTSP_server_port = 4444;
String ServerHost = "10.0.3.2";
try {
InetAddress ServerIPAddr = InetAddress.getByName(ServerHost);
VideoFileName = "media/movie.Mjpeg";
RTSPsocket = new Socket(ServerIPAddr, 4444);
RTSPBufferedReader = new BufferedReader(new InputStreamReader(
RTSPsocket.getInputStream()));
RTSPBufferedWriter = new BufferedWriter(new OutputStreamWriter(
RTSPsocket.getOutputStream()));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.toString());
}
try {
RTPsocket = new DatagramSocket(RTP_RCV_PORT);
RTPsocket.setSoTimeout(5);
} catch (SocketException se) {
System.out.println("Socket exception: " + se);
System.exit(0);
}
RTSPSeqNb = 1;
send_RTSP_request("SETUP");
if (parse_server_response() != 200)
System.out.println("Invalid Server Response");
else {
state = READY;
System.out.println("New RTSP state: READY");
}
System.out.println("Play Button pressed !");
RTSPSeqNb++;
send_RTSP_request("PLAY");
if (parse_server_response() != 200)
System.out.println("Invalid Server Response");
else {
state = PLAYING;
System.out.println("New RTSP state: PLAYING");
new java.util.Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
rcvdp = new DatagramPacket(buf, buf.length);
try {
RTPsocket.receive(rcvdp);
RTPpacket rtp_packet = new RTPpacket(rcvdp.getData(), rcvdp.getLength());
System.out.println("Got RTP packet with SeqNum # "
+ rtp_packet.getsequencenumber() + " TimeStamp "
+ rtp_packet.gettimestamp() + " ms, of type "
+ rtp_packet.getpayloadtype());
rtp_packet.printheader();
int payload_length = rtp_packet.getpayload_length();
byte[] payload = new byte[payload_length];
rtp_packet.getpayload(payload);
bmp = BitmapFactory.decodeByteArray(payload,0,payload_length);
System.out.print("a packet recieved");
} catch (IOException e) {
//e.printStackTrace();
System.out.println("Nothing Recieved");
}
}
}, 0, 200);
}
return null;
}
private int parse_server_response() {
int reply_code = 0;
try {
String StatusLine = RTSPBufferedReader.readLine();
StringTokenizer tokens = new StringTokenizer(StatusLine);
tokens.nextToken();
reply_code = Integer.parseInt(tokens.nextToken());
if (reply_code == 200) {
String SeqNumLine = RTSPBufferedReader.readLine();
String SessionLine = RTSPBufferedReader.readLine();
tokens = new StringTokenizer(SessionLine);
tokens.nextToken();
RTSPid = Integer.parseInt(tokens.nextToken());
}
} catch (Exception ex) {
}
return (reply_code);
}
private void send_RTSP_request(String request_type) {
try {
RTSPBufferedWriter.write(request_type + " " + VideoFileName + " "
+ "RTSP/1.0" + CRLF);
RTSPBufferedWriter.write("CSeq: " + RTSPSeqNb + CRLF);
if (request_type.equals("SETUP")) {
RTSPBufferedWriter.write("Transport: RTP/UDP; client_port= "
+ RTP_RCV_PORT + CRLF);
}
else {
RTSPBufferedWriter.write("Session: " + RTSPid + CRLF);
}
RTSPBufferedWriter.flush();
} catch (Exception ex) {
}
}
}
the error is made by this line of code in the timer object
RTPsocket.receive(rcvdp);
I am wondering the same code works well at java SE .
but in android it sends request to the server to run and stop but I cannot receive packets like in java SE . Thanks.
I have a Server class and a Client class which is run on an android device. Basically, I need to load the user's friends and their IP address. The user's friends are stored in an ArrayList. So the client must send the friend's name and the server will respond with an IP address if the friend is online or a "-1" if the friend is offline. The server has access to all the users and stores it in an Arraylist of my defined type. My problem is that the client doesn't receive the IP Address/"-1" from the server, so only one friend is checked as the server is waiting for a response. The Login of Client is done elsewhere and is working perfectly.
Server:
public class Server {
private static final int port = 9001;
private static final String IPAddr = "xxx.xxx.xx.10";
ServerSocket server = null;
ArrayList <Client> users = new ArrayList<Client>();
public Server(){
readUsers();
try{
server = new ServerSocket(port);
System.out.println("connected server on port" + port);
while(true){
System.out.println("waiting for connection my ip add is "+ InetAddress.getLocalHost().getHostAddress());
Socket clientsocket = server.accept();
System.out.println("Connect to client:"+ clientsocket.getInetAddress().getHostName());
ClientThread client = new ClientThread(clientsocket);
client.start();
}
} catch(IOException e) {
System.err.println("Could not listen on port");
}
}
public void readUsers() {
//read form user text file on start up
ReadFile reader = new ReadFile("users.txt");
try{
String[] data = reader.OpenFile();
for (int i = 0 ; i<data.length; i++){
String[] parts = data[i].split(" ");
ArrayList<String> ips = new ArrayList<String>();
for(int j =2; j<parts.length; j++){
ips.add(parts[j]);
}
Client clnt = new Client(parts[0],parts[1], ips);
users.add(clnt);
}
}catch(Exception e){
System.err.println("Couldn't read in data");
}
}
public void RegisterUser(){
//append to user text if a new user registers
}
//Thread
public class ClientThread extends Thread {
private Socket sckt = null;
private String purpose;
ObjectOutputStream objectOutput;
ObjectInputStream objectInput;
public ClientThread(Socket sckt){
super("ClientThread");
this.sckt = sckt;
}
public void run(){
try{
objectOutput = new ObjectOutputStream(sckt.getOutputStream());
objectOutput.flush();
objectInput = new ObjectInputStream(sckt.getInputStream());
purpose = objectInput.readUTF();
if(purpose.contains("login")){
LoginUser();
}else {
LoadClientIP();
}
} catch(Exception e){
System.err.println("Couldnt read purpose: "+ purpose);
}
}
public void LoginUser(){
try{
String Username = objectInput.readUTF();
String Password = objectInput.readUTF();
int ClientIndex = isClient(Username);
if (ClientIndex != -1){
if(users.get(ClientIndex).password.equals(Password)){
//password correct -> send friends
users.get(ClientIndex).online = true;
users.get(ClientIndex).SetCurrentIP(sckt.getRemoteSocketAddress().toString());
objectOutput.writeUTF("correct");
System.out.println(Username + " is correct");
LoadClientFriends(Username, ClientIndex);
objectOutput.writeObject(users.get(ClientIndex).Friends);
System.out.println("Friends sent");
} else {
//password incorrect -> retry
objectOutput.writeUnshared("password");
System.out.println(Username + " has wrong password");
}
} else {
//not a registered client
objectOutput.writeUTF("wrong");
System.out.println(Username + " is not a client");
}
} catch(Exception e){
System.err.println("Couldnt connect to Client socket");
}
}
public void LoadClientIP(){
try{
int size = Integer.parseInt(objectInput.readUTF()); //keep track of the number of friends
System.out.println("The size of friends:"+ size);
for (int j =0; j<size; j++){
String client = objectInput.readUTF();
System.out.println("Client: "+ client);
int i = isClient(client); //index of friend is user arraylist
if (users.get(i).online == true){
String IP_add = users.get(i).IP.get(users.get(i).CurrentIP);
objectOutput.writeUTF(IP_add);
System.out.println("Client is at index i "+ i + " with IP "+ IP_add);
}else {
objectOutput.writeUTF("-1");
System.out.println("Client is not online");
}
}
System.out.println("out of while");
}catch (Exception e){
System.err.println("Couldn't load IP");
}
}
}
public void LoadClientFriends(String name, int index){
//upon a client signing in, server must load his friends contacts
ReadFile reader = new ReadFile(name+".txt");
try{
String[] data = reader.OpenFile();
for (int i = 0 ; i<data.length; i++){
users.get(index).Friends.add(data[i]);
}
}catch(Exception e){
System.err.println("Couldn't read in friend data");
}
}
public int isClient(String name){
boolean isclient = false;
int i =0;
int index =-1;
while((isclient == false) && (i<users.size())){
if (name.equals(users.get(i).Username)){
isclient = true;
index = i;
}else {
i++;
}
}
return index;
}
public static void main(String[] args){
Server svr = new Server();
}
}
Client/Android:
public class chat_screen extends ActionBarActivity {
ArrayList<String> friends;
ArrayList<String> onlineIP;
ArrayList<String> onlineFriend;
private static final int port = 9001;
private static final String IPAddr = "xx.x.x.4";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_menu);
friends = (ArrayList<String>) getIntent().getSerializableExtra("Friends");
Thread FriendThread = new Thread(Connect);
FriendThread.start();
}
//Thread
Runnable Connect = new Runnable()
{
public void run()
{
try {
//Problems: getting stuck when reading in friends, only is able to send the first friend
Socket connection = new Socket(IPAddr,port);
ObjectOutputStream objectout = new ObjectOutputStream(connection.getOutputStream());
objectout.flush();
ObjectInputStream objectin = new ObjectInputStream(connection.getInputStream());
//send purpose
objectout.writeUTF("load");
objectout.flush();
objectout.writeUTF(Integer.toString(friends.size()));
objectout.flush();
//send friends name to get IP
for(int i =0; i<friends.size(); i++){
objectout.writeUTF(friends.get(i));
objectout.flush();
String ip = objectin.readUTF(); //stuck on this line
if ((ip.contains("-1"))== false){
onlineIP.add(ip);
onlineFriend.add(friends.get(i));
}else {
//do nothing
}
}
connection.close();
}catch (Exception e){
finish();
}
}
};
}
I'm trying to make a chat function with Java. The problem is that I have two classes. One for Client and one for ClientGUI. Where the Client one has the logic parts and the ClientGUI the design. The problem is getting is in row 46 where new ListenFromServer().start(); is getting a error
No enclosing instance of type Controller is accessible. Must
qualify the allocation with an enclosing instance of type
COntroller(e.g. x.new A() where x is an instance of Controller).
So what I did was that I changedpublic class ListenFromServer extends Thread to a static. Which means public static class ListenFromServer extends Thread and now the problem that I'm getting
Error connecting to the server: java.net.ConnectException: connect: Address is invalid on local machine, or port is not valid on remote machine
Controller (Client logic)
package Server;
import java.io.*;
import java.net.*;
import java.util.*;
public class Controller {
private static ObjectInputStream input;
private static ObjectOutputStream output;
private static Socket socket;
private static ClientGUI clientgui;
private static String username;
private static String server;
private static int port;
public static boolean startClient(){
try{
socket = new Socket(server, port);
}catch (Exception ex){
System.out.print("Error connecting to the server: " + ex);
return false;
}
String message = "Connection is accepted; " + socket.getInetAddress() +" - "+ socket.getPort();
System.out.println(message);
try {
input=new ObjectInputStream(socket.getInputStream());
output =new ObjectOutputStream(socket.getOutputStream());
}
catch (IOException io) {
System.out.print("Exception creating new Input/Output Stream: "+ io);
return false;
}
**********new ListenFromServer().start();********* //The problem is here
try {
output.writeObject(username);
}
catch(IOException io) {
System.out.print("Exception doing login: " + io);
disconnect();
return false;
}
return true;
}
private void display(String message) {
if(clientgui == null)
System.out.println(message);
else
clientgui.append(message +"\n");
}
public static void sendMessage(Message message) {
try {
output.writeObject(message);
}
catch(IOException exd) {
System.out.print("Eceptionwritingtoserver: " + exd);
}
}
private static void disconnect() {
try {
if(input != null)
input.close();
}catch (Exception ex){}
try{
if(output != null)
output.close();
}catch(Exception ex){}
try{
if(socket != null)
socket.close();
}catch(Exception ex){};
if (clientgui != null)
clientgui.connectionFailed();
}
public class ListenFromServer extends Thread{
public void run() {
while(true){
try{
String message = (String) input.readObject();
if(clientgui == null){
System.out.println(message);
System.out.print(":");
}
else {
clientgui.append(message);
}
}
catch(IOException io){
System.out.print("Server has closed the connection");
if(clientgui != null)
clientgui.connectionFailed();
break;
}
catch(ClassNotFoundException classex){
}
}
}
}
}
ClientGUI
package Server;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/*
* The Client with its GUI
*/
public class ClientGUI extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
private JLabel lblusername;
private JTextField textfieldusername, textfieldserver, textfieldportnumber;
private JButton btnlogin, btnlogout, btnonline;
private JTextArea textareamessage;
private boolean connected;
private Client client;
private int defaultPort;
private String defaultHost;
ClientGUI(String host, int port) {
super("Chat Client");
defaultPort = port;
defaultHost = host;
JPanel northPanel = new JPanel(new GridLayout(2,2));
JPanel serverAndPort = new JPanel(new GridLayout(1,2, 2, 2));
JLabel lblserveraddress = new JLabel("Server Address: ");
JLabel lblchat = new JLabel(" #BallIsLife");
JLabel lblportnumber = new JLabel("Port Number: ");
textfieldserver = new JTextField(host);
textfieldserver.setHorizontalAlignment(SwingConstants.LEFT);
textfieldserver.setFont(new Font("Tahoma", Font.PLAIN, 20));
textfieldportnumber = new JTextField("" + port);
textfieldportnumber.setFont(new Font("Tahoma", Font.PLAIN, 20));
textfieldportnumber.setHorizontalAlignment(SwingConstants.LEFT);
lblserveraddress.setFont(new Font("Tahoma", Font.PLAIN, 19));
serverAndPort.add(lblserveraddress);
serverAndPort.add(textfieldserver);
serverAndPort.add(lblchat);
serverAndPort.add(lblportnumber);
serverAndPort.add(textfieldportnumber);
lblchat.setForeground(Color.RED);
lblportnumber.setFont(new Font("Tahoma", Font.PLAIN, 19));
northPanel.add(serverAndPort);
getContentPane().add(northPanel, BorderLayout.NORTH);
JPanel panelbtn = new JPanel();
northPanel.add(panelbtn);
btnlogin = new JButton("Login");
panelbtn.add(btnlogin);
btnlogin.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnlogin.addActionListener(this);
btnonline = new JButton("Online");
panelbtn.add(btnonline);
btnonline.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnonline.addActionListener(this);
btnonline.setEnabled(false);
btnlogout = new JButton("Logout");
panelbtn.add(btnlogout);
btnlogout.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnlogout.addActionListener(this);
btnlogout.setEnabled(false);
JButton btnPicture = new JButton("Picture");
btnPicture.setFont(new Font("Tahoma", Font.PLAIN, 17));
btnPicture.setEnabled(false);
panelbtn.add(btnPicture);
textareamessage = new JTextArea("Welcome to the #BallIsLife Chat room.\n");
textareamessage.setFont(new Font("Monospaced", Font.PLAIN, 15));
textareamessage.setLineWrap(true);
textareamessage.setEditable(false);
JPanel centerPanel = new JPanel(new GridLayout(1,1));
JScrollPane scrollPane = new JScrollPane(textareamessage);
centerPanel.add(scrollPane);
getContentPane().add(centerPanel, BorderLayout.CENTER);
JPanel southPanel = new JPanel();
getContentPane().add(southPanel, BorderLayout.SOUTH);
lblusername = new JLabel("Enter your username", SwingConstants.CENTER);
lblusername.setFont(new Font("Tahoma", Font.PLAIN, 15));
southPanel.add(lblusername);
textfieldusername = new JTextField("Write your username here.");
textfieldusername.setFont(new Font("Tahoma", Font.PLAIN, 14));
textfieldusername.setColumns(50);
southPanel.add(textfieldusername);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(823, 665);
setVisible(true);
}
//Logiken
void append(String str) {
textareamessage.append(str);
textareamessage.setCaretPosition(textareamessage.getText().length() - 1);
}
void connectionFailed() {
btnlogin.setEnabled(true);
btnlogout.setEnabled(false);
btnonline.setEnabled(false);
lblusername.setText("Enter your username");
textfieldusername.setText("Write your username here");
textfieldportnumber.setText("" + defaultPort);
textfieldserver.setText(defaultHost);
textfieldserver.setEditable(false);
textfieldportnumber.setEditable(false);
textfieldusername.removeActionListener(this);
connected = false;
}
//
public void actionPerformed(ActionEvent e) {
Object button = e.getSource();
if(button == btnlogout) {
Controller.sendMessage(new Message("", Message.LOGOUT)); //Ändra till Chatmessage klass
btnlogin.setText("Login");
return;
}
if(button == btnonline) {
Controller.sendMessage(new Message("", Message.ONLINE)); //Ändra till Chatmessage klass
return;
}
if(connected) {
Controller.sendMessage(new Message(textfieldusername.getText(), Message.MESSAGE)); //Ändra till Chatmessage klass
textfieldusername.setText("");
return;
}
if(button == btnlogin) {
String username = textfieldusername.getText();
if(username.length() == 0)
return;
String server = textfieldserver.getText();
if(server.length() == 0)
return;
String portNumber = textfieldportnumber.getText();
if(portNumber.length() == 0)
return;
int port = 0;
try {
port = Integer.parseInt(portNumber);
}
catch(Exception en) {
return;
}
client = new Client(server, username, port, this);
if(!Controller.startClient())
return;
}
connected = true;
textfieldusername.setText("");
btnlogin.setText("Send message");
btnlogin.setEnabled(true);
btnlogout.setEnabled(true);
btnonline.setEnabled(true);
textfieldserver.setEditable(false);
textfieldportnumber.setEditable(false);
textfieldusername.addActionListener(this);
}
// to start the whole thing the server
public static void main(String[] args) {
new ClientGUI("localhost", 1500);
}
}
Server
package Server;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
/*
* The server that can be run both as a console application or a GUI
*/
public class Server {
// a unique ID for each connection
private static int uniqueId;
// an ArrayList to keep the list of the Client
private ArrayList<ClientThread> al;
// if I am in a GUI
private ServerGUI sg;
// to display time
private SimpleDateFormat sdf;
// the port number to listen for connection
private int port;
// the boolean that will be turned of to stop the server
private boolean keepGoing;
/*
* server constructor that receive the port to listen to for connection as parameter
* in console
*/
public Server(int port) {
this(port, null);
}
public Server(int port, ServerGUI sg) {
// GUI or not
this.sg = sg;
// the port
this.port = port;
// to display hh:mm:ss
sdf = new SimpleDateFormat("HH:mm:ss");
// ArrayList for the Client list
al = new ArrayList<ClientThread>();
}
public void start() {
keepGoing = true;
/* create socket server and wait for connection requests */
try
{
// the socket used by the server
ServerSocket serverSocket = new ServerSocket(port);
// infinite loop to wait for connections
while(keepGoing)
{
// format message saying we are waiting
display("Server waiting for Clients on port " + port + ".");
Socket socket = serverSocket.accept(); // accept connection
// if I was asked to stop
if(!keepGoing)
break;
ClientThread t = new ClientThread(socket); // make a thread of it
al.add(t); // save it in the ArrayList
t.start();
}
// I was asked to stop
try {
serverSocket.close();
for(int i = 0; i < al.size(); ++i) {
ClientThread tc = al.get(i);
try {
tc.sInput.close();
tc.sOutput.close();
tc.socket.close();
}
catch(IOException ioE) {
// not much I can do
}
}
}
catch(Exception e) {
display("Exception closing the server and clients: " + e);
}
}
// something went bad
catch (IOException e) {
String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";
display(msg);
}
}
/*
* For the GUI to stop the server
*/
protected void stop() {
keepGoing = false;
// connect to myself as Client to exit statement
// Socket socket = serverSocket.accept();
try {
new Socket("localhost", port);
}
catch(Exception e) {
// nothing I can really do
}
}
/*
* Display an event (not a message) to the console or the GUI
*/
private void display(String msg) {
String time = sdf.format(new Date()) + " " + msg;
if(sg == null)
System.out.println(time);
else
sg.appendRoom(null,time + "\n");
}
/*
* to broadcast a message to all Clients
*/
private synchronized void broadcast(String message) {
// add HH:mm:ss and \n to the message
String time = sdf.format(new Date());
String messageLf = time + " " + message + "\n";
// display message on console or GUI
if(sg == null)
System.out.print(messageLf);
else
sg.appendRoom(messageLf,null); // append in the room window
// we loop in reverse order in case we would have to remove a Client
// because it has disconnected
for(int i = al.size(); --i >= 0;) {
ClientThread ct = al.get(i);
// try to write to the Client if it fails remove it from the list
if(!ct.writeMsg(messageLf)) {
al.remove(i);
display("Disconnected Client " + ct.username + " removed from list.");
}
}
}
// for a client who logoff using the LOGOUT message
synchronized void remove(int id) {
// scan the array list until we found the Id
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
// found it
if(ct.id == id) {
al.remove(i);
return;
}
}
}
/*
* To run as a console application just open a console window and:
* > java Server
* > java Server portNumber
* If the port number is not specified 1500 is used
*/
public static void main(String[] args) {
// start server on port 1500 unless a PortNumber is specified
int portNumber = 1500;
switch(args.length) {
case 1:
try {
portNumber = Integer.parseInt(args[0]);
}
catch(Exception e) {
System.out.println("Invalid port number.");
System.out.println("Usage is: > java Server [portNumber]");
return;
}
case 0:
break;
default:
System.out.println("Usage is: > java Server [portNumber]");
return;
}
// create a server object and start it
Server server = new Server(portNumber);
server.start();
}
/** One instance of this thread will run for each client */
class ClientThread extends Thread {
// the socket where to listen/talk
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
// my unique id (easier for deconnection)
int id;
// the Username of the Client
String username;
// the only type of message a will receive
Message cm;
// the date I connect
String date;
// Constructore
ClientThread(Socket socket) {
// a unique id
id = ++uniqueId;
this.socket = socket;
/* Creating both Data Stream */
System.out.println("Thread trying to create Object Input/Output Streams");
try
{
// create output first
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
// read the username
username = (String) sInput.readObject();
display(username + " just connected.");
}
catch (IOException e) {
display("Exception creating new Input/output Streams: " + e);
return;
}
// have to catch ClassNotFoundException
// but I read a String, I am sure it will work
catch (ClassNotFoundException e) {
}
date = new Date().toString() + "\n";
}
// what will run forever
public void run() {
// to loop until LOGOUT
boolean keepGoing = true;
while(keepGoing) {
// read a String (which is an object)
try {
cm = (Message) sInput.readObject();
}
catch (IOException e) {
display(username + " Exception reading Streams: " + e);
break;
}
catch(ClassNotFoundException e2) {
break;
}
// the messaage part of the ChatMessage
String message = cm.getMessage();
// Switch on the type of message receive
switch(cm.getType()) {
case Message.MESSAGE:
broadcast(username + ": " + message);
break;
case Message.LOGOUT:
display(username + " disconnected with a LOGOUT message.");
keepGoing = false;
break;
case Message.ONLINE:
writeMsg("List of the users connected at " + sdf.format(new Date()) + "\n");
// scan al the users connected
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
writeMsg((i+1) + ") " + ct.username + " since " + ct.date);
}
break;
}
}
// remove myself from the arrayList containing the list of the
// connected Clients
remove(id);
close();
}
// try to close everything
private void close() {
// try to close the connection
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {};
try {
if(socket != null) socket.close();
}
catch (Exception e) {}
}
/*
* Write a String to the Client output stream
*/
private boolean writeMsg(String msg) {
// if Client is still connected send the message to it
if(!socket.isConnected()) {
close();
return false;
}
// write the message to the stream
try {
sOutput.writeObject(msg);
}
// if an error occurs, do not abort just inform the user
catch(IOException e) {
display("Error sending message to " + username);
display(e.toString());
}
return true;
}
}
}
ServerGUI
package Server;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
/*
* The server as a GUI
*/
public class ServerGUI extends JFrame implements ActionListener, WindowListener {
private static final long serialVersionUID = 1L;
// the stop and start buttons
private JButton stopStart, saveLog;
// JTextArea for the chat room and the events
private JTextArea chat;
// private JTextArea event;
// The port number
private JTextField tfPortNumber;
// my server
private Server server;
// server constructor that receive the port to listen to for connection as
// parameter
ServerGUI(int port) {
super("Chat Server");
server = null;
// in the NorthPanel the PortNumber the Start and Stop buttons
JPanel north = new JPanel();
north.add(new JLabel("Port number: "));
tfPortNumber = new JTextField("" + port);
north.add(tfPortNumber);
// to stop or start the server, we start with "Start"
stopStart = new JButton("Start");
stopStart.addActionListener(this);
saveLog = new JButton("Save log");
saveLog.addActionListener(this);
north.add(stopStart);
north.add(saveLog);
add(north, BorderLayout.NORTH);
// the event and chat room
JPanel center = new JPanel(new GridLayout());
chat = new JTextArea(120, 20);
chat.setEditable(false);
chat.setWrapStyleWord(true);
chat.setLineWrap(true);
appendRoom(null, "Chat room and Events log for server.\n");
center.add(new JScrollPane(chat));
// event = new JTextArea(80,80);
// event.setEditable(false);
// appendEvent("Events log.\n");
// center.add(new JScrollPane(event));
add(center);
// need to be informed when the user click the close button on the frame
addWindowListener(this);
setSize(450, 600);
setVisible(true);
}
public void writeLog() {
try {
JFileChooser chooser = new JFileChooser();
String content = chat.getText();
int actionDialog = chooser.showSaveDialog(this);
content = content.replaceAll("(?!\\r)\\n", "\r\n");
if (actionDialog == JFileChooser.APPROVE_OPTION) {
File file = new File(chooser.getSelectedFile() + ".txt");
// if file doesnt exists, then create it
// if (!file.exists()) {
// file.createNewFile();
// }
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
}
} catch (IOException ee) {
ee.printStackTrace();
}
// JFileChooser chooser = new JFileChooser();
// // chooser.setCurrentDirectory(new File("./"));
// int actionDialog = chooser.showSaveDialog(this);
// if (actionDialog == JFileChooser.APPROVE_OPTION) {
// File fileName = new File(chooser.getSelectedFile() + "");
// if (fileName == null)
// // return;
// if (fileName.exists()) {
// actionDialog = JOptionPane.showConfirmDialog(this,
// "Replace existing file?");
// if (actionDialog == JOptionPane.NO_OPTION)
// return;
// }
// try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
// new FileOutputStream(fileName), "ISO-8859-1"))) {
// bw.write(saveText);
// // bw.newLine();
// bw.flush();
// }
// }
}
// append message to the two JTextArea
// position at the end
void appendRoom(String chatStr, String eventStr) {
chat.append(chatStr);
chat.append(eventStr);
// chat.setCaretPosition(chat.getText().length() - 1);
}
// void appendEvent(String str) {
// event.append(str);
// event.setCaretPosition(chat.getText().length() - 1);
//
// }
// start or stop where clicked
public void actionPerformed(ActionEvent e) {
// if running we have to stop
if (e.getSource() == saveLog) {
writeLog();
} else if (e.getSource() == stopStart) {
if (server != null) {
server.stop();
server = null;
tfPortNumber.setEditable(true);
stopStart.setText("Start");
return;
}
// OK start the server
int port;
try {
port = Integer.parseInt(tfPortNumber.getText().trim());
} catch (Exception er) {
appendRoom(null, "Invalid port number");
return;
}
// ceate a new Server
server = new Server(port, this);
// and start it as a thread
new ServerRunning().start();
stopStart.setText("Stop");
tfPortNumber.setEditable(false);
}
}
/*
* A thread to run the Server
*/
class ServerRunning extends Thread {
public void run() {
server.start(); // should execute until if fails
// the server failed
stopStart.setText("Start");
tfPortNumber.setEditable(true);
appendRoom(null, "Server closed\n");
server = null;
}
}
// entry point to start the Server
public static void main(String[] arg) {
// start server default port 1500
new ServerGUI(1500);
}
/*
* If the user click the X button to close the application I need to close
* the connection with the server to free the port
*/
public void windowClosing(WindowEvent e) {
// if my Server exist
if (server != null) {
try {
server.stop(); // ask the server to close the conection
} catch (Exception eClose) {
}
server = null;
}
// dispose the frame
dispose();
System.exit(0);
}
// I can ignore the other WindowListener method
public void windowClosed(WindowEvent e) {
}
public void windowOpened(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
// /*
// * A thread to run the Server
// */
// class ServerRunning extends Thread {
// public void run() {
// server.start(); // should execute until if fails
// // the server failed
// stopStart.setText("Start");
// tfPortNumber.setEditable(true);
// appendRoom(null, "Server closed\n");
// server = null;
// }
// }
}
Message
package Server;
import java.io.Serializable;
//Klassen som kollar vad för typ av message
public class Message implements Serializable {
protected static final long serialVersionUID = 42L;
static final int ONLINE = 0;
static final int MESSAGE = 1;
static final int LOGOUT = 2;
private int SAVELOG = 3;
private String message;
private int type;
public Message(String message, int type){
this.type = type;
this.message = message;
}
public int getType(){
return type;
}
public String getMessage(){
return message;
}
}
Make your inner class ListenFromServer static, since you are referring to it from a static method
public class Controller {
...
public static class ListenFromServer {
...
}
}