this is the scenario .. i have 2 clients connected to a server.. i want them to be able to chat with eachother. After a couple of messages i get this error.
Exception in thread "Thread-0" java.lang.ClassCastException:
java.io.ObjectStreamClass cannot be cast to message.Mesaj
at server.ServerThread.readAndWrite(ServerThread.java:43)
at server.ServerThread.run(ServerThread.java:61)
java.io.StreamCorruptedException: invalid type code: 00
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at server.ServerThread.readAndWrite(ServerThread.java:43)
at server.ServerThread.run(ServerThread.java:61)
This is the client:
package client;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import message.Mesaj;
public class Client {
public static int port=4321;
public static Socket socket;
public static ObjectOutputStream oo;
public static ObjectInputStream oi;
public static Scanner sc;
public Client() throws IOException{
socket = new Socket ("localhost",4321);
oi = new ObjectInputStream(socket.getInputStream());
oo = new ObjectOutputStream(socket.getOutputStream());
}
public static void listen() throws ClassNotFoundException, IOException{
while(true){
Mesaj m = (Mesaj) oi.readObject();
if(m!=null){
System.out.println("mesajul este: " + m.getMesaj());
}
}
}
public static void write() throws IOException{
sc= new Scanner(System.in);
while(true){
String trimite= sc.nextLine();
Mesaj m = new Mesaj();
m.setMesaj(trimite);
oo.writeObject(m);
oo.flush();
}
}
public static Thread t = new Thread(){
public void run(){
try {
listen();
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public static Thread t2 = new Thread(){
public void run(){
try {
write();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public static void main(String[] args) throws IOException{
new Client();
t.start();
t2.start();
}
This is the Server:
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
public int port;
public static Socket socket;
public static ServerSocket serverSocket;
public Server() throws IOException{
this.port=4321;
serverSocket = new ServerSocket(port);
}
public static void main (String [] args){
try {
new Server();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Server functionabil..asteptam conexiune client");
while(true){
try {
socket= serverSocket.accept();
ServerThread st= new ServerThread(socket);
st.start();
System.out.println("Conexiune realizata -client conectat");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
..and this is the Server Thread:
package server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import message.Mesaj;
public class ServerThread extends Thread {
boolean running;
public static ObjectOutputStream oo;
public static ObjectInputStream oi;
public static Mesaj m;
public static Socket socket;
public ServerThread(Socket socket) throws ClassNotFoundException{
try {
running=true;
this.socket=socket;
oo = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void readAndWrite() throws ClassNotFoundException, IOException{
oi = new ObjectInputStream(socket.getInputStream());
while(true){
m= (Mesaj) oi.readObject();
if(m!=null){
oo.writeObject(m);
oo.flush();
System.out.println(m.getMesaj());
}
}
}
public void run(){
System.out.println("Server Thread contectat");
try {
readAndWrite();
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
EDIT:
This is the message class:
package message;
import java.io.Serializable;
public class Mesaj implements Serializable {
private String mesaj;
public String getMesaj() {
return mesaj;
}
public void setMesaj(String mesaj) {
this.mesaj = mesaj;
}
}
You having concurrency issues.
Both serverthreads access the same static outputstream, meaning that there is a change for corruption as Object streams aren't designed for this.
In ServerThread, remove static from all the variables and the method "readAndWrite".
public ObjectOutputStream oo;
public ObjectInputStream oi;
public Mesaj m;
public Socket socket;
...
public void readAndWrite() throws ClassNotFoundException, IOException{
If you want to access the output streams from multiple threads, you should synchronize on them.
Related
I Have implemented a server and client using sockets. In that multiple clients must able to connected.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Set;
import sensors.FireAlarmSensor;
public class SensorServer {
private static final int port = 9000;
private static HashMap<String, PrintWriter> fireSensorPrintersList = new HashMap<String, PrintWriter>();
private static HashMap<String,FireAlarmSensor> fireSensorsList = new HashMap<String,FireAlarmSensor>();
private static String sensorIDNumber;
private static double temperatureLevel;
private static double CO2Level;
private static double batteryLevel;
private static double smokeLevel;
public static void main(String args[]){
System.out.println("Sensor Server Is Running");
ServerSocket clientListener = null;
try {
clientListener = new ServerSocket(port);
new sensorHandler(clientListener.accept()).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try {
clientListener.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static class sensorHandler extends Thread{
private String sensorID;
private Socket socket;
private BufferedReader receiver;
private PrintWriter sender;
public sensorHandler(Socket socket) {
this.socket = socket;
try {
this.receiver = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.sender = new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run(){
while(true){
sender.println("REQUESTID");
try {
sensorID = receiver.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(sensorID == null){
System.out.println("Empty Sensor ID");
}
synchronized (fireSensorPrintersList) {
if(!fireSensorPrintersList.containsKey(sensorID)){
fireSensorPrintersList.put(sensorID,sender);
break;
}
}
}
sender.println("SENSORACCEPTED");
try{
while(true){
//Set<String> sensorIDList= fireSensorPrintersList.keySet();
/*for(PrintWriter writer:fireSensorPrintersList.values()){
sensorIDNumber = fireSensorsList.get(sensorIDList).getSensorID();
temperatureLevel = fireSensorsList.get(sensorIDList).getTemperatureLevel();
batteryLevel = fireSensorsList.get(sensorIDList).getBatteryLevel();
CO2Level = fireSensorsList.get(sensorIDList).getCO2Level();
smokeLevel = fireSensorsList.get(sensorIDList).getSmokeLevel();
}*/
/*try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
}
finally {
try {
socket.close();
System.out.println("Sensor server closed");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Here is the code of client(Sensor).
package sensors;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Serializable;
import java.net.Socket;
import java.util.Scanner;
public class FireAlarmSensor implements Serializable{
BufferedReader lineIn;
PrintWriter lineOut;
private String sensorID = "Not Set";
private BatterySensor batterySensor;
private TemperatureSensor temperatureSensor;
private SmokeSensor smokeSensor;
private CO2Sensor co2Sensor;
public FireAlarmSensor(String sensorID){
this.sensorID = sensorID;
this.batterySensor = new BatterySensor();
this.temperatureSensor = new TemperatureSensor();
this.smokeSensor = new SmokeSensor();
this.co2Sensor = new CO2Sensor();
}
public FireAlarmSensor(){
/*JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);*/
}
public String getSensorID(){
return this.sensorID;
}
public double getBatteryLevel(){
return batterySensor.getSensorData();
}
public double getTemperatureLevel(){
return temperatureSensor.getSensorData();
}
public double getSmokeLevel(){
return smokeSensor.getSensorData();
}
public double getCO2Level(){
return co2Sensor.getSensorData();
}
public void run(){
String serverAddress = "localhost";
Socket socket = null;
try {
socket = new Socket(serverAddress,9000);
lineIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
lineOut = new PrintWriter(socket.getOutputStream(),true);
while(true){
String serverInput = lineIn.readLine();
if(serverInput.startsWith("REQUESTID")){
Scanner userInput = new Scanner(System.in);
System.out.print("Enter the Sensor ID : ");
String sensorID = userInput.nextLine();
lineOut.println(sensorID);
}
else if(serverInput.startsWith("SENSORACCEPTED")){
System.out.println("Sensor Is Accepted");
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*finally{
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
}
public static void main(String args[]){
FireAlarmSensor sensor = new FireAlarmSensor();
sensor.run();
}
}
Server is working perfectly fine in my program. It doesn't crash anytime and first sensor also can connected with the server and it also never get crashed. But when try to connect another sensor to a server by running the FireAlarmSensor.class file, 2nd sensor gives me following exception and crash.
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at sensors.FireAlarmSensor.run(FireAlarmSensor.java:64)
at sensors.FireAlarmSensor.main(FireAlarmSensor.java:96)
I'm running server and all the sensors in same machine using eclipse neon.
Lines from 16 to 27 in Client(Sensor) cause an errors because I haven't uploaded that java files.Please comment or delete them when you running it.
The main method only calls accept once, so it is not surprising that only one client can connect. Try accepting clients in a loop:
private static boolean shouldExit = false;
public static void main(String args[]) {
System.out.println("Sensor Server Is Running");
try (ServerSocket listener = new ServerSocket(port)) {
acceptLoop(listener);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void acceptLoop(ServerSocket listener) throws IOException {
while (!shouldExit) {
// accept() blocks until a connection is made
Socket client = listener.accept();
new sensorHandler(client).start();
}
}
What this will do is just loop forever, accepting new clients until you set shouldExit to be true. The main thread, that is.
I've taken the liberty to make use of the Java 7 try-with-resources statement (try (ServerSocket listener = ...)). It does essentially what your convoluted try-catch-finally did - automatically closes the ServerSocket.
The class Server:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server{
private int port;
private Socket client;
private ServerSocket server;
public Server(int port) {
try {
this.port = port;
setServer(new ServerSocket(this.port));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.start();
}
public void start() {
ArrayList<ClientHandler> clients = new ArrayList<>();
ExecutorService executor = Executors.newFixedThreadPool(20);
System.out.println("Server started...");
while (true) {
try {
setClient(null);
setClient(getServer().accept());
if (getClient() != null) {
ClientHandler handler = new ClientHandler(getClient());
System.out.println("Client connected...");
clients.add(handler);
executor.execute(handler);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Server server = new Server(4567);
}
public Socket getClient() {
return client;
}
public void setClient(Socket client) {
this.client = client;
}
public ServerSocket getServer() {
return server;
}
public void setServer(ServerSocket server) {
this.server = server;
}
}
Now, my Question is, is there a Problem in the class, which causes the UnknownHostException? I already tried to debug, but the problem lies in the class Client
The Class Client:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client{
private String kennung;
private Socket server;
private String host;
private int port;
public Client(String kennung, String host, int port){
setKennung(kennung);
setHost(host);
setPort(port);
try {
setServer(new Socket(this.host, this.port));
//Scanner reader = new Scanner(this.server.getInputStream());
PrintWriter writer = new PrintWriter(getServer().getOutputStream(), true);
Scanner sc = new Scanner(System.in);
writer.println("The Client");
/*while(true){
boolean next = reader.hasNext();
if (next) {
String line = reader.nextLine();
if(!line.equals(null)){
System.out.println("From another one: " + line);
}
}
writer.println(sc.next());
}*/
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if( server != null){
try {
server.close();
} catch (IOException e) {
//ignore -> Server getting closed
}
}
}
}
public String getKennung() {
return kennung;
}
public void setKennung(String kennung) {
this.kennung = kennung;
}
public Socket getServer() {
return server;
}
public void setServer(Socket server) {
this.server = server;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public static void main(String[] args) {
Client testClient = new Client("testClient", "127.0.0.1", 4567);
System.out.println("Client created");
}
}
And Last, but not least: The Class ClientHandler that implements Runnable and runs a Thread, where I read the input from the client and write it to the server.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
public class ClientHandler implements Runnable {
public ArrayBlockingQueue<String> messsages;
Socket client;
public ClientHandler(Socket client) {
this.messsages = new ArrayBlockingQueue<>(20);
this.client = client;
}
#Override
public void run() {
PrintWriter writer = null;
Scanner reader = null;
try {
reader = new Scanner(this.client.getInputStream());
writer = new PrintWriter(this.client.getOutputStream(), true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String line = "";
while (!line.equals(".bye")) {
//System.out.println("Got something? " + reader.hasNext());
line = reader.nextLine();
if (reader.hasNext()) {
if (!line.equals(null)) {
System.out.println("Vom Client: " + line);
}
}
//writer.println("Admin-Message"); // Zum Testen
}
}
}
Thanks to everybody, who helps me with this problem.
I have code which works with one client connection. What I need is ability for the server to handle multiple client requests using multithreaded approach.
I found some solutions, but it's not meet my requirements, like this, or this
Server.java
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends User {
private Socket clientSocket;
private ServerSocket serverSocket;
public Server() {
super();
}
private void createConnection() {
try {
InetAddress locIP = InetAddress.getByName("127.0.0.1");
serverSocket = new ServerSocket(9999, 0, locIP);
// serverSocket = new ServerSocket(4444, 4444, InetAddress.getByName("192.168.0.101"));
} catch (IOException e) {
System.err.println("Could not listen on port: 9999 ." + e);
System.exit(1);
}
}
private void closeConnection() {
try {
serverSocket.close();
} catch (IOException e) {
System.err.println(e);
}
}
#Override
public void connect() {
createConnection();
//Socket clientSocket=null;
try {
clientSocket = serverSocket.accept();
System.out.println("Client connected! "
+ "IP: "
+ clientSocket.getInetAddress()
+ ", port: "
+ clientSocket.getPort());
} catch (IOException e) {
System.err.println("Accept failed. " + e);
System.exit(1);
}
}
#Override
public void disconnect() {
try {
clientSocket.close();
} catch (IOException e) {
System.err.println(e);
}
closeConnection();
}
#Override
public Socket getSocket() {
return clientSocket;
}
#Override
public String toString() {
return new String("Server");
}
}
Client.java
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client extends User {
private Socket socket;
public Client() {
super();
}
#Override
public Socket getSocket() {
return socket;
}
#Override
public void connect() {
try {
InetAddress locIP = InetAddress.getByName("127.0.0.1");
// socket = new Socket(9999, 0, locIP);
// socket = new Socket("localhost", 9999); oryginalny
socket = new Socket(locIP, 9999);
} catch (UnknownHostException e) {
System.err.println("The host not found! " + e);
System.exit(1);
} catch (IOException e) {
System.err.println("Can't find connection! " + e);
System.exit(1);
}
}
#Override
public void disconnect() {
try {
socket.close();
} catch (IOException e) {
System.err.println(e);
}
}
#Override
public String toString() {
return new String("Client");
}
}
SendButton.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import javax.swing.JButton;
import javax.swing.JTextPane;
#SuppressWarnings("serial")
public class SendButton extends JButton {
private JTextPane incomingMessages;
private JTextPane messageToSend;
private User user;
public SendButton(User user, JTextPane incomingMessages, JTextPane messageToSend) {
super("Send!");
this.user = user;
this.incomingMessages = incomingMessages;
this.messageToSend = messageToSend;
this.addActionListener(new SendListener());
}
public class Write {
private PrintStream out;
public Write() {
try {
out = new PrintStream(new BufferedOutputStream(
user.getSocket().getOutputStream(), 1024), false);
} catch (IOException e) {
System.err.println(e);
}
}
public void send(String message) {
if (message != null) {
out.println(message);
out.flush();
incomingMessages.setText(new String(incomingMessages.getText() + "\nMe: " + message));
}
}
}
public class SendListener implements ActionListener {
private Write write = new Write();
private String toSend;
#Override
public void actionPerformed(ActionEvent event) {
toSend = messageToSend.getText();
if (toSend != null || event.getActionCommand() == "\n") {
write.send(toSend);
}
messageToSend.setText(new String(""));
}
}
}
You need to create a new Runnable class, whose data members consist of a Socket and its input and output streams. This class is used on the server side. Its run() method is responsible for all I/O to that client. Then your accept() loop just looks like this:
while (true)
{
new Thread(new ConnectionHandler(serverSocket.accept())).start();
}
where ConnectionHandler implements Runnable as above.
simply what you need to do is after accepting the request from the client (Using main thread), then the request pass to a new thread with the client socket and process the request inside the new thread. So the main thread is free to accept new requests.
I made client server app, which is joining new clients in new thread each. I want to send information to server like in auction system bidding up value. How Can I check if thread in client class is the same as in server class? If not How Can I check in which Thread on server side is client?
package com.multi;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import oracle.jdbc.driver.OracleDriver;
public class Server {
public static final int PORT = 5545;
public static int I = 1;
public static String[] users = null;
private static final String URL = "jdbc:oracle:thin:#localhost:1521:XE";
Connection conn = null;
Statement stmt = null;
private static final String DB_USER = "DBDEMO";
private static final String DB_PASSWORD = "******";
private ResultSet res;
private String sql = null;
public void startDataBase() {
try {
DriverManager.registerDriver(new OracleDriver());
conn = DriverManager.getConnection(URL, DB_USER, DB_PASSWORD);
System.out.println("conn done");
conn.setAutoCommit(false);
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void runQuery(){
try {
stmt = conn.createStatement();
res = stmt.executeQuery("select * from ITEAMS");
System.out.println("query works");
while(res.next()){
System.out.println(res.getString("DESCRIBE"));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void startServer() {
try {
ServerSocket server = new ServerSocket(PORT);
System.out.println("Server is waiting for connetions...");
startDataBase();
runQuery();
while (true) {
Socket socket = server.accept();
if (socket.isBound()) {
System.out.println("user" + I + " connected");
++I;
}
new ServerThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Server().startServer();
}
}
//serverthreads
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ServerThread extends Thread {
Socket socket;
String message = null;
ServerThread(Socket socket) {
this.socket = socket;
}
public void run(){
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while ((message = bufferedReader.readLine()) != null){
System.out.println(message);
}
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//client
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
public class Client extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
private static String[] names = new String[]{ "Sara", "Jessica", "Tom", "Emanuel", "Joshua",
"Kristin", "Kirito", "Goku", "Bulma" };
private JTextField chatWindow;
private static int c = 0;
public void clientJoin(String name) {
try {
chatWindow = new JTextField();
add(new JScrollPane(chatWindow));
setSize(300, 150);
setVisible(true);
Socket socket = new Socket("localhost", 5545);
chatWindow.setText(name);
PrintWriter printWriter = new PrintWriter(
socket.getOutputStream(), true);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(System.in));
// System.out.println(name);
// System.out.println(name);
// while (true) {
// String readerInput = bufferedReader.readLine();
for(int i = 0 ; i < 3;i++){
printWriter.print(name+":" );
printWriter.println(c+=5+10*Math.random());
}
// }
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
for(String name : names) {
Runnable r = new Runnable() {
#Override
public void run() {
new Client().clientJoin(name);
}
};
new Thread(r).start();
// System.out.println("ges here");
c++;
}
}
}
How Can I check if thread in client class is the same as in server class?
Unless the Client and Server classes are running in the same JVM (i.e. on the same machine and in the same process), they cannot share threads. They cannot be the same.
Furthermore, since the client and server threads are instances of different classes: Thread and ServerThread respective. That means that even if Client and Server were instantiated in the same JVM, the respective threads still could not be the same.
(Two objects with different classes cannot be the same. Especially threads, since thread equality is determined by object identity.)
As you can see, the question makes little sense if you interpret it literally. If you are actually trying to ask something different ... you will need to clarify the question.
I have gone through a lot of threads and blogs/examples outside SO but I just can't get my code to work. The code is very similar to what others have posted but this thing just won't work .. Here is a brief outline of the code.
Server Class implements Runnable
Creates new ServerSocket(PORT, Numberof Users)
Uses serverSocket.Accept() to get the socket and stores it in ArrayList.
Sends a welcome message to socket The code uses print writer on OUTPUTSTREAM on Socket.
(this part actually works and I get the message back)
Client Class
socket = new Socket(localhost, PORT);
In a separate thread start reader which reads from socket.inputstream and puts it on chat window.
In a separate thread write to socket.output stream.
This is mostly same as server side code
So when I test the code. The server starts. The client opens up swing window. It connects to server. It gets the server welcome message back. But when I write something it does not return back the text that I just sent. it just stays at readLine and never come back. I had a similar issue in echoserver code which I fixed (thanks to SO !) using threads. Now both reader and writer are in separate thread, so I am not sure whats wrong.
Thanks in advance! Apologies if you think its a repeated thread but I just can't fix my code on my own !
Here is the full code:
Server Class:
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
public class ChatServer implements Runnable {
private static int port;
private static String ip_add;
private Socket socket;
private ArrayList<Socket> clients;
private ServerSocket ss;
public ChatServer(String ip_add_in, int port_in) {
// TODO Auto-generated constructor stub
port = port_in;
ip_add = ip_add_in;
clients = new ArrayList<Socket>();
}
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("ChatServer Start!!" + new Date() );
try {
ss = new ServerSocket(port, 10);
while(true){
socket = ss.accept();
System.out.println("ChatServer Accepts!!" + new Date() );
clients.add(socket);
sendWelcomeMessage();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendWelcomeMessage() {
try {
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println("Welcome To Chat Server");
writer.flush();
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class transmitMessages implements Runnable {
#Override
public void run() {
// TODO Auto-generated method stub
while(true){
if (ss.isBound()) {
for (Socket sock : clients) {
}
}
}
}
}
}
Client Class:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;
import javax.swing.*;
public class Chat1 {
JFrame frame;
JPanel msg_pan, chat_pan;
JButton send;
JTextArea type_area, chat_area;
private static String user;
private SendMsg send_action = new SendMsg();
private Socket writerSocket;
// private Socket readerSocket;
static String ip_address;
static int port;
private PrintWriter writer;
private ReaderThread readerRunner;
private SenderThread senderRunner;
Thread senderThread;
Thread readerThread;
public Chat1(String name){
user = name;
}
public void create_window() {
frame = new JFrame(user);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
chat_pan = new JPanel();
// Adding Main Chat Area
chat_area = new JTextArea(30,50);
chat_area.setEditable(false);
chat_area.setLineWrap(true);
JScrollPane chat_scroll = new JScrollPane(chat_area);
chat_scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
chat_scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
chat_pan.add(chat_scroll);
msg_pan = new JPanel();
send = new JButton("Send");
send.addActionListener(send_action);
type_area = new JTextArea(5,50);
type_area.setLineWrap(true);
JScrollPane type_scroll = new JScrollPane(type_area);
type_scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
msg_pan.add(type_scroll);
msg_pan.add(send);
msg_pan.setLayout(new BoxLayout(msg_pan, BoxLayout.X_AXIS));
frame.getContentPane().add(BorderLayout.SOUTH, msg_pan);
frame.getContentPane().add(BorderLayout.CENTER, chat_pan);
frame.setSize(600, 600);
frame.setVisible(true);
frame.pack();
}
public static void main(String ip_add_in, int port_in) {
// TODO Auto-generated method stub
ip_address = ip_add_in;
port = port_in;
Chat1 user1 = new Chat1("User1");
user1.startchat();
}
class SendMsg implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String msg = type_area.getText();
if (msg != null) {
senderRunner = new SenderThread(msg);
senderThread = new Thread(senderRunner);
senderThread.start();
}
type_area.setText(null);
}
}
public void setup_connection() {
}
public void startchat(){
connect_socket();
create_window();
System.out.println("Window Done");
readerRunner = new ReaderThread();
readerThread = new Thread(readerRunner);
readerThread.start();
System.out.println("Thread Started");
}
public void connect_socket(){
try {
System.out.println("Start Chat" + new Date());
writerSocket = new Socket(ip_address,port);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class ReaderThread implements Runnable {
InputStreamReader streamReader;
BufferedReader reader;
String msg;
public void run(){
try {
System.out.println("Entered ReaderThread Run");
streamReader = new InputStreamReader(writerSocket.getInputStream());
reader = new BufferedReader(streamReader);
while (true) {
msg = reader.readLine();
if (msg != null) {
chat_area.append(msg);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Leaving ReaderThread Run");
}
}
public class SenderThread implements Runnable{
String msg;
public SenderThread(String msg_in){
msg = msg_in;
}
public void run(){
System.out.println("Entered SenderThread Run" + msg);
try {
if (writer == null) {
writer = new PrintWriter(writerSocket.getOutputStream());
}
System.out.println("Writer has Error-->" + writer.checkError());
writer.println(msg);
writer.flush();
writer.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
System.out.println("Sender Thread Run Exception 1");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Sender Thread Run Exception 2");
e.printStackTrace();
}
System.out.println("Leaving SenderThread Run");
}
}
}
Tester Class:
import java.util.*;
public class ChatTester {
public static void main(String[] args) {
// TODO Auto-generated method stub
ChatServer serverRunner = new ChatServer("127.0.0.1", 5000);
Thread serverThread = new Thread(serverRunner);
serverThread.start();
System.out.println("Server Started" + new Date());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread clientThread = new Thread() {
public void run() {
Chat1.main("127.0.0.1", 5000);
}
};
clientThread.start();
System.out.println("Client Started" + new Date());
}
}
You are closing the writer after every send, which also closes the underlying socket output stream. You can see this in your test output:
Writer has Error-->false (before first send)
Writer has Error-->false (before second send, output is already closed!)
Writer has Error-->true (before third send, second send failed because the stream is closed)
The server on the other hand does not listen for any incoming messages. It only sends the welcome message and then closes the output stream!
The server needs to keeps reading the input streams of the client sockets. When it receives a message, it should write it to the output streams of the clients.
Do not close the streams as long as you are communication with the clients.
Below is a simple example of how to receive messages and send a reply.
First remove writer.close() in both SenderThread and sendWelcomeMessage().
Start a new handler thread for each connection (note: starting a new thread for each connection might not be the best practice for "real" applications).
while(true){
socket = ss.accept();
System.out.println("ChatServer Accepts!!" + new Date() );
clients.add(socket);
sendWelcomeMessage();
(new Thread(new ClientHandler(socket))).start();
}
In the thread, listen for incoming messages and send them back.
public class ClientHandler implements Runnable {
private Socket socket;
private BufferedReader reader;
private BufferedWriter writer;
public ClientHandler(Socket socket)
{
this.socket = socket;
}
#Override
public void run() {
try
{
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String message = reader.readLine();
while (message != null)
{
writer.write(message + System.lineSeparator());
writer.flush();
message = reader.readLine();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Note that the ClientHandler thread only echoes the received message back to the sender. In a real chat, these messages would be sent to all connected clients, for example in your transmitMessages class, that does not do anything at the moment.