EOFException / SocketException when working with sockets and threads - java

This socket application works perfectly fine until I add support for multiple client connections to the server. Then I get a EOFException from the client, and a SocketException: Socket closed from the server.
Server.java:
public class Server {
static final int PORT = 8005;
static final int QUEUE = 50;
public Server() {
while (true) {
try (ServerSocket serverSocket = new ServerSocket(PORT, QUEUE);
Socket socket = serverSocket.accept();
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream())) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
output.writeUTF("Hey, this is the server!");
output.flush();
System.out.println(input.readUTF());
} catch (IOException e) {
System.out.println();
e.printStackTrace();
}
}
});
thread.start();
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Server();
}
}
Client.java:
public class Client {
static final String HOST = "localhost";
static final int PORT = 8005;
public Client() {
try (Socket socket = new Socket(HOST, PORT);
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream())
) {
System.out.println(input.readUTF());
output.writeUTF("Hey, this is the client!");
output.flush();
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
new Client();
}
}

A couple problems here:
You're creating a new ServerSocket for each pass through the loop. For a multi-client server you should instead be opening one ServerSocket and calling accept() on it for each client that connects.
Try-with-resources closes all resources it's provided with as soon as the try block is exited. You're creating a Thread that uses output but executes independently of the try block, so the execution flow is leaving the try block before thread finishes executing, resulting in socket (and output) being closed before the thread is able to use them. This is one of those situations where your resources need to be used outside the scope of the try block (in the thread you create to use them), so try-with-resources can't do all your resource handling for you.
I would rearrange your server code to something like:
public class Server {
static final int PORT = 8005;
static final int QUEUE = 50;
public Server() {
// create serverSocket once for all connections
try (ServerSocket serverSocket = new ServerSocket(PORT, QUEUE)) {
while (true) {
// accept a client connection, not in a try-with-resources so this will have to be explicitly closed
final Socket socket = serverSocket.accept();
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
// limit scope of input/output to where they're actually used
try (DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream())) {
output.writeUTF("Hey, this is the server!");
output.flush();
System.out.println(input.readUTF());
} catch (IOException e) {
System.out.println();
e.printStackTrace();
}
// implicitly close socket when done with it
try {
socket.close();
} catch (IOException e) {
System.out.println();
e.printStackTrace();
}
}
});
thread.start();
}
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
public static void main(String[] args) {
new Server();
}
}
Code is commented somewhat to explain some of the moves. Also note that the socket.close() call is in its own try-catch block to ensure that it's called even if the I/O streams throw an exception. It could equivalently (or perhaps more correctly now that I think about it) been placed in a finally block on the I/O stream try-catch block.

Related

Java Sockets - EOFException when trying to implement multi-threading

I think it's because when I multi-thread the client&server, the DataOutputStream and DataInputStream buffers I use get overwritten or something like that since the socket can only have 1 duplex connection.
Here's what I have for now:
Client Class in my client program:
public static void main(String args[]) throws UnknownHostException, IOException, InterruptedException {
for (int i=0;i<2;i++) //change limit on i to change number of threads
{
new Thread(new ClientHandler(i)).start();
}
Thread.sleep(10000);
ClientHandler class in my client program:
(Sends a value to the server, the server will echo it back).
public class ClientHandler implements Runnable {
public int clientNumber;
public ClientHandler(int i){
this.clientNumber=i;
}
public void run() {
Socket socket = null;
try {
socket = new Socket("localhost",9990);
System.out.println("connected client number "+clientNumber);
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
DataInputStream input = new DataInputStream(socket.getInputStream());
output.writeDouble((new Random()).nextDouble());
System.out.println(input.readDouble());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
Server Class in my server program:
ServerSocket socket = new ServerSocket(9990);
try {
while (true) {
Socket threadSocket = socket.accept();
new Thread(new ServerHandler(threadSocket)).start();
Thread.sleep(10000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
socket.close();
}
}
}
ServerHandler Class in my server program (receives value from client and echoes it back)
public class ServerHandler implements Runnable {
private Socket socket;
public ServerHandler(Socket socket) {
this.socket = socket;
}
public void run() {
while(true) {
try {
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
double a = input.readDouble();
output.writeDouble(a);
}catch (IOException e){
e.printStackTrace();
}
}
}
So it's a pretty straight-forward implementation: create multiple threads of the client, and connect them to multiple threads of the server.
Everything works fine until the line:
double a = input.readDouble();
in my ServerHandler class.
I get an EOFException
I'm guessing it's because there can only be a single duplex connection between sockets. But if that's the case then how would I implement multi-threading of sockets at all?
So my question is: how can I get rid of the EOFException and allow myself to perform multi-threaded client-server socket interaction?
(preferably not changing much about my code because it's taken me a long time to get to this point).
The problem is that you share same Socket variable in ServerHandler for all threads:
private static Socket socket
Remove static keyword. Your ServerHandler will be something like this:
public static class ServerHandler implements Runnable {
private Socket socket;
public ServerHandler(Socket socket) {
this.socket = socket;
}
public void run() {
try {
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
double a = input.readDouble();
output.writeDouble(a);
} catch (IOException e) {
e.printStackTrace();
}
}
}

How to write A ServerSocket which accept multiple clicent Socket?

I am working on Socket programming. I have build such a server which should accept multiple Clients. Here I have particular num of clients , clients keeps on sending msg to Server every 10sec , Server has to process it.The problem I am having is I am unable to connect multiple Server and here a single client is a continuous running programm in while(true) So if one client Sends a request another client can not connect . Here is my Program.
Server
public class SimpleServer extends Thread {
private ServerSocket serverSocket = null;
private Socket s1 = null;
SimpleServer() {
try {
serverSocket = new ServerSocket(1231);
this.start();
} catch (IOException ex) {
System.out.println("Exception on new ServerSocket: " + ex);
}
}
public void run() {
while (true) {
try {
System.out.println("Waiting for connect to client");
s1 = serverSocket.accept();
System.out.println("Connection received from " + s1.getInetAddress().getHostName());
InputStream s1In = s1.getInputStream();
DataInputStream dis = new DataInputStream(s1In);
String st = dis.readUTF();
System.out.println(st);
s1In.close();
dis.close();
s1.close();
// throw new ArithmeticException();
} catch (IOException ex) {
Logger.getLogger(SimpleServer.class.getName()).log(Level.SEVERE, null, ex);
}
catch (Exception e) {
System.out.println("Exceptiopn: "+e);
}
}
}
public static void main(String args[]) throws IOException {
new SimpleServer();
}
}
Server is working fine but I am not able to write Client program which shoud run in while(true) loop for sending msg to Server and allow other client also connect to Server.
but for a single client I write like this ,
public class SimClient extends Thread {
private Socket s1 = null;
SimClient() {
//this.start();
}
public void run() {
int i=0;
try {
s1 = new Socket("localhost", 1231);
} catch (IOException ex) {
Logger.getLogger(SimClient.class.getName()).log(Level.SEVERE, null, ex);
}
// while (i<10) {
try {
// Open your connection to a server, at port dfg1231
OutputStream s1out = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream(s1out);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter Data from Client:");
String s = br.readLine();
dos.writeUTF(s);
dos.flush();
s1out.close();
dos.close();
// s1.close();
i++;
} catch (IOException ex) {
//ex.printStackTrace();
System.out.println("Exception in While: "+ex.getMessage());
}
//}
}
public static void main(String args[]) throws IOException {
SimClient s= new SimClient();
s.start();
}
}
So can any one help me to write client program. its a great help for me.
just as you have a Thread for the ServerSocket, you need to create a Thread for every Socket returned by serverSocket.accept() , then it loops back around immediately to block and wait to accept another Socket. Make a class called SocketHander which extends Thread and accepts a Socket in the constructor.
public class SocketHandler extends Thread {
private Socket socket;
public SocketHandler(Socket socket) {
this.socket = socket;
}
public void run() {
// use the socket here
}
}
and back in the ServerSocket handler...
for (;;) {
SocketHandler socketHander = new SocketHandler(serverSocket.accept());
socketHander.start();
}
It is generally a good idea to use a Fixed Size Thread Pool because creating Threads in a ad-hoc manner may cause the Server to run out of Threads if the requests are high.
public class SimpleServer extends Thread {
private ServerSocket serverSocket = null;
private static ExecutorService executor = Executors.newFixedThreadPool(100);
SimpleServer() {
try {
serverSocket = new ServerSocket(1231);
this.start();
} catch (IOException ex) {
System.out.println("Exception on new ServerSocket: " + ex);
}
}
public void run() {
while (true) {
try {
System.out.println("Waiting for connect to client");
final Socket s1 = serverSocket.accept();
executor.execute(new Runnable() {
public void run() {
try {
System.out.println("Connection received from " + s1.getInetAddress().getHostName());
InputStream s1In = s1.getInputStream();
DataInputStream dis = new DataInputStream(s1In);
String st = dis.readUTF();
System.out.println(st);
s1In.close();
dis.close();
s1.close();
} catch(Exception e) {
System.out.println("Exceptiopn: "+e);
}
// throw new ArithmeticException();
}});
} catch (IOException ex) {
Logger.getLogger(SimpleServer.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception e) {
System.out.println("Exceptiopn: "+e);
}
}
}
public static void main(String args[]) throws IOException {
new SimpleServer();
}
}

Sending a message to all clients (Client - Server communication)

So now, I am making a client server app based multithread. In server side, I make a thread for everysingle connection that accepted.
In thread class, I make a method that send a command to client. What i just want is, how to send a parameter to all running client? For simple statement, i just want to make this server send a message to all connected client.
I've been read this post and find sendToAll(String message) method from this link. But when i am try in my code, there is no method like that in ServerSocket .
Okay this is my sample code for server and the thread.
class ServerOne{
ServerSocket server = null;
...
ServerOne(int port){
System.out.println("Starting server on port "+port);
try{
server = new ServerSocket(port);
System.out.println("Server started successfully and now waiting for client");
} catch (IOException e) {
System.out.println("Could not listen on port "+port);
System.exit(-1);
}
}
public void listenSocket(){
while(true){
ClientWorker w;
try{
w = new ClientWorker(server.accept());
Thread t = new Thread(w);
t.start();
} catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
}
}
protected void finalize(){
try{
server.close();
} catch (IOException e) {
System.out.println("Could not close socket");
System.exit(-1);
}
}
}
class ClientWorker implements Runnable{
Socket client;
ClientWorker(Socket client){
this.client = client;
}
public void run(){
...
sendCommand(parameter);
...
}
public void sendCommand(String command){
PrintWriter out = null;
try {
out = new PrintWriter(client.getOutputStream(), true);
out.println(command);
} catch (IOException ex) {}
}
}
Thanks for help :)
The below answer, is not recommended for a full fledged server, as for this you should use Java EE with servlets, web services etc.
This is only intended where a few computers want to connect to perform a specific task, and using simple Java sockets is not a general problem. Think of distributed computing or multi-player gaming.
EDIT: I've - since first post - greatly updated this architecture, now tested and thread-safe. Anybody who needs it may download it here.
Simply use (directly, or by subclassing) Server and Client, start() them, and everything is ready. Read the inline comments for more powerful options.
While communication between clients are fairly complicated, I'll try to simplify it, the most possible.
Here are the points, in the server:
Keeping a list of connected clients.
Defining a thread, for server input.
Defining a queue of the received messages.
A thread polling from the queue, and work with it.
Some utility methods for sending messages.
And for the client:
Defining a thread, for client input.
Defining a queue of the received messages.
A thread polling from the queue, and work with it.
Here's the Server class:
public class Server {
private ArrayList<ConnectionToClient> clientList;
private LinkedBlockingQueue<Object> messages;
private ServerSocket serverSocket;
public Server(int port) {
clientList = new ArrayList<ConnectionToClient>();
messages = new LinkedBlockingQueue<Object>();
serverSocket = new ServerSocket(port);
Thread accept = new Thread() {
public void run(){
while(true){
try{
Socket s = serverSocket.accept();
clientList.add(new ConnectionToClient(s));
}
catch(IOException e){ e.printStackTrace(); }
}
}
};
accept.setDaemon(true);
accept.start();
Thread messageHandling = new Thread() {
public void run(){
while(true){
try{
Object message = messages.take();
// Do some handling here...
System.out.println("Message Received: " + message);
}
catch(InterruptedException e){ }
}
}
};
messageHandling.setDaemon(true);
messageHandling.start();
}
private class ConnectionToClient {
ObjectInputStream in;
ObjectOutputStream out;
Socket socket;
ConnectionToClient(Socket socket) throws IOException {
this.socket = socket;
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
Thread read = new Thread(){
public void run(){
while(true){
try{
Object obj = in.readObject();
messages.put(obj);
}
catch(IOException e){ e.printStackTrace(); }
}
}
};
read.setDaemon(true); // terminate when main ends
read.start();
}
public void write(Object obj) {
try{
out.writeObject(obj);
}
catch(IOException e){ e.printStackTrace(); }
}
}
public void sendToOne(int index, Object message)throws IndexOutOfBoundsException {
clientList.get(index).write(message);
}
public void sendToAll(Object message){
for(ConnectionToClient client : clientList)
client.write(message);
}
}
And here for the Client class:
public class Client {
private ConnectionToServer server;
private LinkedBlockingQueue<Object> messages;
private Socket socket;
public Client(String IPAddress, int port) throws IOException{
socket = new Socket(IPAddress, port);
messages = new LinkedBlokingQueue<Object>();
server = new ConnecionToServer(socket);
Thread messageHandling = new Thread() {
public void run(){
while(true){
try{
Object message = messages.take();
// Do some handling here...
System.out.println("Message Received: " + message);
}
catch(InterruptedException e){ }
}
}
};
messageHandling.setDaemon(true);
messageHandling.start();
}
private class ConnectionToServer {
ObjectInputStream in;
ObjectOutputStream out;
Socket socket;
ConnectionToServer(Socket socket) throws IOException {
this.socket = socket;
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
Thread read = new Thread(){
public void run(){
while(true){
try{
Object obj = in.readObject();
messages.put(obj);
}
catch(IOException e){ e.printStackTrace(); }
}
}
};
read.setDaemon(true);
read.start();
}
private void write(Object obj) {
try{
out.writeObject(obj);
}
catch(IOException e){ e.printStackTrace(); }
}
}
public void send(Object obj) {
server.write(obj);
}
}
There is no method in server socket to send data or message to all running clinet threads.
Please go through the ServerThread.java program which is calling the sendToAll usng server.
// ... and have the server send it to all clients
server.sendToAll( message );
Check out zeroMQ. There are methods known as "pub sub" or "publish subscribe" that will do what you want. You can also use it to communicate between your threads. It is an amazing library in my opinion. It has java or jzmq bindings along with over 30+ others as well so you should be able to use it in your program.
http://www.zeromq.org/

Multithreading Socket communication Client/Server

I finished writing a Client/Server Socket communication program that works fine. Now I'm trying to figure out how to make it so that I can have multiple Client connections to the Server at once. I've looked around and there seems to be more than a couple of different ways to do this. so I've come here to ask you guys for help/suggestions.
My Server:
public class Server {
private ServerSocket serverSocket = null;
private Socket clientSocket = null;
public Server() {
try {
serverSocket = new ServerSocket(7003);
} catch (IOException e) {
System.err.println("Could not listen on port: 7003");
System.exit(1);
}
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed");
System.exit(1);
}
}
public void startServer() throws IOException {
PrintWriter output = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine, outputLine;
outputLine = "Connected to Server";
output.println(outputLine);
while ((inputLine = input.readLine()) != null) {
// This just determines users input and server ruturns output based on that
outputLine = this.getServerOutput(inputLine);
output.println(outputLine);
if (outputLine.equals("Bye"))
break;
}
output.close();
input.close();
clientSocket.close();
serverSocket.close();
}
}
Would I need to make my constructor create threads and startServer() or would be my run method?
You should use ExecutorService. Your client request processing would be the run() of a Runnable and after each accept you can call ExecutorService.submit(runnableTask) to asynchronously service the client.
A sample using ExecutorService.
public class MyServer {
private static MyServer server;
private ServerSocket serverSocket;
/**
* This executor service has 10 threads.
* So it means your server can process max 10 concurrent requests.
*/
private ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws IOException {
server = new MyServer();
server.runServer();
}
private void runServer() {
int serverPort = 8085;
try {
System.out.println("Starting Server");
serverSocket = new ServerSocket(serverPort);
while(true) {
System.out.println("Waiting for request");
try {
Socket s = serverSocket.accept();
System.out.println("Processing request");
executorService.submit(new ServiceRequest(s));
} catch(IOException ioe) {
System.out.println("Error accepting connection");
ioe.printStackTrace();
}
}
}catch(IOException e) {
System.out.println("Error starting Server on "+serverPort);
e.printStackTrace();
}
}
//Call the method when you want to stop your server
private void stopServer() {
//Stop the executor service.
executorService.shutdownNow();
try {
//Stop accepting requests.
serverSocket.close();
} catch (IOException e) {
System.out.println("Error in server shutdown");
e.printStackTrace();
}
System.exit(0);
}
class ServiceRequest implements Runnable {
private Socket socket;
public ServiceRequest(Socket connection) {
this.socket = connection;
}
public void run() {
//Do your logic here. You have the `socket` available to read/write data.
//Make sure to close
try {
socket.close();
}catch(IOException ioe) {
System.out.println("Error closing client connection");
}
}
}
}
how to make it so that I can have multiple Client connections to the Server at once
Right now you are starting your server and immediately waiting for a single client to connect in the constructor.
clientSocket = serverSocket.accept();
Then you handle that single socket connection inside of your startServer() method. This means that no other clients will be handled.
public void startServer() throws IOException {
PrintWriter output = new PrintWriter(clientSocket.getOutputStream(), true);
...
Typically with a server pattern like this, you would do something like the following:
Setup your server socket in the constructor.
Create an acceptClients() method which would loop waiting for a client to be accepted. This could fork a thread to accept the clients in a thread of its own in the background.
For each client, either fork a thread to handle the connection, passing the thread the clients socket. Better would be to, as #basiljames shows, use an ExecutorService to manage the threads for you.
Here's some sample code:
public class Server {
private ServerSocket serverSocket = null;
public Server(int portNumber) throws IOException {
serverSocket = new ServerSocket(portNumber);
}
// this could be run in a thread in the background
public void acceptClients() throws IOException {
// create an open ended thread-pool
ExecutorService threadPool = Executors.newCachedThreadPool();
try {
while (!Thread.currentThread().isInterrupted()) {
// wait for a client to connect
Socket clientSocket = serverSocket.accept();
// create a new client handler object for that socket,
// and fork it in a background thread
threadPool.submit(new ClientHandler(clientSocket));
}
} finally {
// we _have_ to shutdown the thread-pool when we are done
threadPool.shutdown();
}
}
// if server is running in background, you stop it by killing the socket
public void stop() throws IOException {
serverSocket.close();
}
// this class handles each client connection
private static class ClientHandler implements Runnable {
private final Socket clientSocket;
public ClientHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public void run() {
// use the client socket to handle the client connection
...
}
}
}
Using the ExecutorService thread-pools is recommended for just about all Thread implementations like this. If, however, you are stuck to using raw Thread for some reason, you can do the following instead in your acceptClients() method:
public void acceptClients() throws IOException {
while (!Thread.currentThread().isInterrupted()) {
// wait for a client to connect
Socket clientSocket = serverSocket.accept();
// fork a background client thread
new Thread(new ClientHandler(clientSocket)).start();
}
}
Change this: public void startServer() throws IOException
To this: public void startServer(Socket clientSocket) throws IOException
Then all you need to do is:
public Server()
{
try
{
serverSocket = new ServerSocket(7003);
}
catch (IOException e)
{
System.err.println("Could not listen on port: 7003");
System.exit(1);
}
try
{
while(true) {
final Socket socket = serverSocket.accept();
new Thread(new Runnable() {
public void run() {
try {
startServer(socket);
} catch(IOException e) {e.printStackTrace();}
}
}).start();
}
}
catch(IOException e)
{
System.err.println("Accept failed");
System.exit(1);
}
}
And lastly, you can remove private Socket clientSocket = null;
That should get you there. Or at least pretty close.
private static final int SERVER_PORT = 35706;
private ServerSocket serverSocket;
private final ArrayList<ClientThread> activeClients = new ArrayList<>();
public void startServer() {
try {
serverSocket = new ServerSocket(SERVER_PORT);
final ExecutorService clientPool = Executors.newCachedThreadPool();
while (!serverSocket.isClosed()) {
try {
Future<Socket> future = clientPool.submit(() -> {
Socket socket = serverSocket.accept();
ClientThread clientThread= new ClientThread(socket);
return (socket);
});
activeClients.add(future.get());
} catch (IOException e) {
clientPool.shutdownNow();
System.out.println(e.getMessage());
} catch (InterruptedException | ExecutionException e) {
System.out.println(e.getMessage());
}
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
public void stopServer() {
try {
serverSocket.close();
activeClients.forEach(socket -> {
try {
socket.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
});
} catch (IOException ex) {
System.out.println(e.getMessage());
}
}
private static class ClientThread implements Runnable{
private final Socket socket;
public ClientThread(Socket socket) throws IOException {
this.socket = socket;
}
#Override
public void run() {
/* Your implementation */
}
}

Java - Listening to a socket with ObjectInputStream

Ok so , i have a thread class called 'Client' every time the server accepts a connection it creates a new Client....The run method listens for messages from the client and i am useing ObjectInputStream ..
do {
ObjectInputStream in = null;
try {
in = new ObjectInputStream(socket.getInputStream());
String message = (String) in.readObject();
System.out.println(message);
}
catch (ClassNotFoundException ex) {
isConnected = false;
System.out.println("Progoramming Error");
}
catch (IOException ex) {
isConnected = false;
System.out.println("Server ShutDown");
System.exit(0);
}
} while(isConnected);
The Problem i have is that why do i have to create a new ObjectInputStream every time it loops...and if i close the input stream at the end of the loop and it loops again for another message i will get a error...Please some one help
Only create the ObjectInputStream once (outside the loop) for a client connection, then put the readObject method into the loop.
Here's a working test class:
public class TestPrg {
public static void main(String... args) throws IOException {
ServerListener server = new ServerListener();
server.start();
Socket socketToServer = new Socket("localhost", 15000);
ObjectOutputStream outStream = new ObjectOutputStream(socketToServer.getOutputStream());
for (int i=1; i<10; i++) {
try {
Thread.sleep((long) (Math.random()*3000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Sending object to server ...");
outStream.writeObject("test message #"+i);
}
System.exit(0);
}
static class ServerListener extends Thread {
private ServerSocket serverSocket;
ServerListener() throws IOException {
serverSocket = ServerSocketFactory.getDefault().createServerSocket(15000);
}
#Override
public void run() {
while (true) {
try {
final Socket socketToClient = serverSocket.accept();
ClientHandler clientHandler = new ClientHandler(socketToClient);
clientHandler.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
static class ClientHandler extends Thread{
private Socket socket;
ObjectInputStream inputStream;
ClientHandler(Socket socket) throws IOException {
this.socket = socket;
inputStream = new ObjectInputStream(socket.getInputStream());
}
#Override
public void run() {
while (true) {
try {
Object o = inputStream.readObject();
System.out.println("Read object: "+o);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
}
In this example Strings are sent trough the ObjectStream. If you get the ClassNotFoundException (http://download.oracle.com/javase/6/docs/api/java/io/ObjectInputStream.html#readObject()) and are using an independent client and server program than you might check if both the client and the server have the class of the object to send in their class paths.
The problem i personally had with Sockets and ObjectIOStream, is that it remembers all your object addresses, so each time you send and recive them on the client, if the address of sent object is not changed it will be copied from buffer. So
So
or create new objects each time you send them ( this is not a bad idiea, because ObjectIOStream seems to has limits on this buffer)
or use another Stream for these perpouse

Categories

Resources