For the server I have to alter the provided code into a multi-threaded server. For the client I have alter to it to make it read data from a text file.
So far I've managed to compile but when running on the client side it not only gives odd symbols but in the end it says "connection host lost". I've tried changing the socket number the same problem persists.
So this is what it looks like:
¼Ýsr♥Car´3▼3çw3û☻♦DmileageLmodelt↕Ljava/lang/String;Lownerq~☺L
registrationq~☺xp#
"Honda Civic""John S"q~sq~##t-sq~#Òêt
"Vokswagen"t "Maria B"q~
Connection to host lost.
This is my code for server:
//a simple client/server application: car registration
//a SERVER program that uses a stream socket connection to exchange objects
import java.net.*;
import java.io.*;
public class CarsServer {
public static void main(String[] args) throws IOException{
ServerSocket serverSocket = null;; // TCP socket used for listening
try {
/* step 1: create a server socket port number: 8000 */
serverSocket = new ServerSocket(5200);
int i = 0;
for(;;){
/* setp 2: listen for a connection and create a socket */
System.out.println("*** this server is going to register the cars ***");
System.out.println("listening for a connection...");
Socket clientSocket = serverSocket.accept();
System.out.println("Spawning " + i++);
new CarsClient(clientSocket, i).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
/* step 5: close the connection to the client */
System.out.println("*** the server is going to stop running ***");
serverSocket.close();
}
}
}
And for Client
//a simple client/server application that exchanges OBJECTS
//a CLIENT program that uses a stream socket connection to exchange objects
import java.net.*;
import java.io.*;
class CarsClient extends Thread{
private Socket incoming;
private int client;
public CarsClient(Socket i, int c){
this.client = c;
this.incoming = i;
}
public void run(){
try {
/*
* step 2: connect input and output streams to the socket
*/
BufferedReader oisFromServer = new BufferedReader(new FileReader("Cars.txt"));
ObjectOutputStream oosToServer = new ObjectOutputStream(incoming.getOutputStream());
System.out.println("I/O streams connected to the socket");
/*
* step 3: communicate with the server
*/
Car[] cars = new Car[3];
int n = 0;
String[] l;
String line;
while((line = oisFromServer.readLine()) != null){
l = line.split(", ");
try {
// receive an object from the server
cars[n] = new Car(l[0], l[1], Integer.parseInt(l[2])); // casting!
// send an object to the server
oosToServer.writeObject(cars[n]);
//oosToServer.flush();
System.out.println("\n### send this car to the server for registration:\n" + cars[n]);
System.out.println("\t###### the car returned by the server:\n"+ cars[n]);
n++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
} catch (EOFException eof) {
System.out.println("The server has terminated connection!");
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* step 4: close the connection to the server
*/
System.out.println("\nClient: closing the connection...");
oosToServer.close();
oisFromServer.close();
incoming.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
System.out.println("the client is going to stop runing...");
} // end run
}
I'm new to programming so please help me out.
It appears that your issue is here:
while((line = oisFromServer.readLine()) != null){
You are consuming all the lines of text, and once that's done, oisFromServer is going to return null.
To solve this, I recommend you use the raw InputStream and InputStream.read() from the socket. Also, once upon a time I wrote a utility class for this kind of blocking reading. See DataFetcher, and its dependencies in the same project package
Related
I created 2 Java programs with sockets in it. I want the client to send continuous data to the server. But after the message sent to the server, the client keeps sending 'null' value to the server (it happens when I close the socket in client program).
Here is my codes:
import ...
public class MainClient {
private Socket serverSock;
private PrintStream clientOutput;
public static void main(String[] args) {
MainClient client = new MainClient();
client.runClient();
}
public void runClient() {
try {
serverSock = new Socket("127.0.0.1",8282);
clientOutput = new PrintStream(serverSock.getOutputStream());
clientOutput.println("Hello, I'm Connected.");
for (int i=0;i<5;i++) {
clientOutput.println(i + "");
clientOutput.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
// try {
// serverSock.close(); It will keeps sending 'null' data to the server if I use this line.
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
}
The Server Side:
public class MainServer {
private ServerSocket serverSocket;
private int listenPort = 8282;
private InputStream inps;
private Socket clientSocket;
private BufferedReader clientInput;
private MainServer() {
String clientMsg = "";
try {
serverSocket = new ServerSocket(listenPort);
System.out.println("Server is Listening on " + listenPort);
clientSocket = serverSocket.accept();
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while(clientSocket.isConnected()) {
clientMsg = clientInput.readLine();
System.out.println("Client : " + clientMsg);
}
}catch(IOException ex) {
ex.printStackTrace();
}finally {
try {
clientSocket.close();
} catch (IOException e) {}
}
}
public static void main(String[] args) {
new MainServer();
}
}
I tried to close the OutputStream on the Client side with clientOutput.close(); but it sends nulls to the server after it sends the 0-4 loop.
To make it stop and avoid the client sends null data, i should not insert the serverSock.close(); on the Client, but it will returns SocketException. I wanted the client to send 'Closed' message after its done.
Summary, the output on the server is:
Client: 0
Client: 1
Client: 2
Client: 3
Client: 4
Client: null
Client: null
//And so on..
I think there is something missing on the Client Program, i guess?
Thank you for the help :)
As the comment noted, the client is not sending a null value.
The isConnected() method does not do what you think it does, namely it does not tell you if the socket is currently "connected" to its peer, at least in the way you think it should. isConnected() becomes true as soon as the socket transitions into the connected state, and stays true thereafter, even after the socket is shutdown. See this discussion and others on stackoverflow.
The correct way to determine if the peer has shutdown the connection is to attempt to read from the socket and then examine the result for evidence of closure. Please read the Javadocs for the method you are using, they will tell you what the various return values mean. For the BufferedReader.readLine() method, it says:
Returns:
A String containing the contents of the line, not including
any line-termination characters, or null if the end of the stream has
been reached
Throws:
IOException - If an I/O error occurs
Thus you need to check for a null return value to detect a normal socket closure, and if you receive an IOException that indicates some kind of network anomaly.
Your MainClient() have no problem.
clientSocket.isConnected() function in MainServer() always check the status of the client and which results an infinite loop, so after the message 'client:4', clientInput.readLine() should return 'null'.
So instead of checking the client socket is connected or not you can check the client socket is closed or not using function 'clientSocket.isClosed()'.
replace the while loop in MainServer() with below code,
while(!clientSocket.isClosed()) {
clientMsg = clientInput.readLine();
System.out.println("Client : " + clientMsg);
if(clientMsg.equals("Closed")){
clientSocket.close();
// serverSocket.close();
}
}
this will help you to close the client socket at the time of receiving 'Closed' message from server and this avoid the infinite execution of while loop as well as null statement printing.
The code "serverSocket.close()" help you to close the server socket and you can use this at 'MainServer()' if you need to stop the port listening.
typically the code should be something similar
private MainServer() {
String clientMsg = "";
try {
serverSocket = new ServerSocket(listenPort);
System.out.println("Server is Listening on " + listenPort);
clientSocket = serverSocket.accept();
clientInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while ((clientMsg = clientInput.readLine()) != null) {
if(isTerminationString(clientMsg)) {
break;
}
System.out.println("Client : " + clientMsg);
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
}
}
}
boolean isTerminationString(String msg) {
return msg.equals("DONE!");
}
where in isTerminationString you check if the msg is a termination msg, the communication protocol should be shared between the client and the server . i gave the example of sending
a DONE message, but it could more complex than that .
as closing the close method on the socket does not guarantee that the socket on the other part gets closed as well, using the isClosed method might not be effective and results in the same problem you have .
I am trying to open a socket inside a bukkit plugin so i could send data to it using php or node but instead of socket remaining open after one use it just closes and also server does not load before this happens what should i do i am out of ideas.
Main:
public class Main extends JavaPlugin {
public void onEnable() {
saveDefaultConfig();
getConfig().options().copyDefaults(true);
System.out.println("[INFO] Main class loaded.");
start();
}
public void start() {
SocketServer server = new SocketServer();
try {
server.start(getConfig().getInt("port"), getConfig().getString("socket-password"));
System.out.println("[INFO] Main successfully called start.");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Socket server class:
When called this should read information convert it into array check the first item in array and use it as auth code then array should be converted into string and used in Command executor class. This works fine but after one use this just closes
public class SocketServer {
private ServerSocket serverSocket;
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public void start(int port, String socketpwd) throws IOException {
System.out.println("[INFO] Socket server listening on: " + port);
serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
Boolean enabled = true;
try {
// Socket authentication
String message = in.readLine();
String suffix[] = message.split(" ");
System.out.println("Socket auth code used: "+ suffix[0]);
System.out.println("Socket pwd is: " + socketpwd);
if (socketpwd.equals(suffix[0])) {
out.println("Auth sucessfull!");
// do the following command from args here
String command = suffix[1];
int suffixL = suffix.length;
// add arguments to command
for (int i = 2; i < suffixL; i++) {
command = command + " " + suffix[i];
}
// call req exec
System.out.println("[INFO] Socket server contacted Request executor with: " + command);
RequestExecutor.executor(command);
enabled = false;
}
else {
out.println("Unrecognised auth code!");
}
} catch (NullPointerException e) {
System.out.println("Exception prevented!");
}
}
public void stop() throws IOException {
in.close();
out.close();
clientSocket.close();
serverSocket.close();
}
}
Other problem as i mentioned is that bukkit server does not fully load before one request has been made to this socket.
Thank you for your help.
First of all you shouldn't be running a socket like that on the main thread, typically you should be running this on an async task using the Bukkit scheduler.
Then once you open the socket you should create a while loop to continuously poll for a connection and handle the incoming data. Instead what you are doing is opening the socket, reading a line and then dropping the connection.
You want to be doing something similar to
while(true){
Socket socket = serverSocket.accept();
}
See this webpage for some more info.
This is the Problem Statement i Was Given :
Design a protocol where a server is responsible to match up two chatt clients. The server listens on a TCP port for upcoming connections.
If no client is already connected to the server to be paired, the server accepts the connecting client, and makes it wait for another client. To do that, it sends a message to the connecting client to wait. When recieving this command the client constructs another Server Socket instance to listen on a port . The client then sends a mesagge to the server that contains the port number in which the newly created server listens on.
When another client, C2, seeks a connection with the server while C1 is waiting, the server informs C2 the existence of C1 by sending a message “PEER_LOC $h:$p” to C2, where $h is the host name (or IP address) of C1 and $p is the port number on which C1 is waiting. After C2 receives this message, it seeks a connection to C1 using the obtained information.Clients get the messages from users. The two clients then exchange messages until either party sends an end of stream” (Ctrl-D in Linux). Their conservation is then terminated.Sophisticated methods may employ multiple threads, timeouts, etc., and is not required in this problem.
My issues is connecting two clients to my Server. I run my server program and then two other clients classes that are duplicated of each other only with different names. I can connect to one of them only the other one just seems to wait forever.
Theses are my classes I run.
The server:
package chatserver2;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
// import all the class that you will need for functionailty
// extends jframe to develop gui's in java
public class Server {
private static ObjectOutputStream output; // stream data out
private static ObjectInputStream input; // stream data in
private static ServerSocket server;
private static Socket connection; // socket means set up connetion between 2 computers
private static int n;
//Constructor
public static void main(String[] args) throws IOException {
Server obj = new Server();
obj.RunServer();
try {
while (true) {
Handler obj2 = new Handler();
obj2.start();
System.out.println("Accepted connection from "
+ connection.getInetAddress() + " at port "
+ connection.getPort());
n++;
System.out.println("Count " + n);
}
} finally {
connection.close();
}
}
public Server() {
}
// run the server after gui created
public void RunServer() {
try {
server = new ServerSocket(6789); // 1st number is port number where the application is located on the server, 2nd number is the amount of people aloud to connect
while (true) {
try {
waitForConnection(); // wait for a connection between 2 computers
setupStreams(); // set up a stream connection between 2 computers to communicate
whileChatting(); // send message to each other
// connect with someone and have a conversation
} catch (EOFException eofException) {
}
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
//Wait for a connection then display connection information
private void waitForConnection() {
try {
connection = server.accept();
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
// stream function to send and recive data
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream()); // set up pathway to send data out
output.flush(); // move data away from your machine
input = new ObjectInputStream(connection.getInputStream()); // set up pathway to allow data in
}
// this code while run during chat conversions
private void whileChatting() throws IOException {
String message = "WAIT ";
sendMessage(message);
do {
try {
message = (String) input.readObject(); // stores input object message in a string variable
System.out.println("Message from Client " + message);
} catch (ClassNotFoundException classnotfoundException) {
}
} while (!message.equals("CLIENT - END"));// if user types end program stops
}
private void closeChat() {
try {
output.close();
input.close();
connection.close();
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
// send message to the client
private void sendMessage(String message) {
try {
output.writeObject(message);
output.flush();
System.out.println("Message to client " + message);
} catch (IOException ioexception) {
}
}
public static class Handler extends Thread {
private Socket connection;
public Handler() {
String message = "WAIT";
}
public void run() {
System.out.println("Connect" + Server.connection);
while (true) {
try {
waitForConnection();
setupStreams();
whileChatting();
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
private void waitForConnection() {
System.out.println("server" + server);
try {
connection = server.accept();
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
System.out.println("Connection" + connection);
}
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream()); // set up pathway to send data out
output.flush(); // move data away from your machine
input = new ObjectInputStream(connection.getInputStream()); // set up pathway to allow data in
}
private void whileChatting() throws IOException {
String message = " You are now connected ";
sendMessage(message);
do {
try {
message = (String) input.readObject();
} catch (ClassNotFoundException classnotfoundException) {
}
} while (!message.equals("CLIENT - END"));
}
private void closeChat() {
try {
output.close();
input.close();
connection.close();
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
static private void sendMessage(String message) {
try {
output.writeObject(message);
output.flush();
} catch (IOException ioexception) {
}
}
}
}
The and one duplicated client classes C1, or C2:
package chatserver2;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// import all the class that you will need for functionailty
// extends jframe to develop gui's in java
public class Client1 extends JFrame {
private JTextField userInput; //
private JTextArea theChatWindow; //
private ObjectOutputStream output; // stream data out
private ObjectInputStream input; // stream data in
private Socket connection; // socket means set up connetion between 2 computers
//Constructor
public Client1() {
}
// run the server after gui created
public void RunClient() {
try {
connection = new Socket("localhost", 6789);// 1st number is port number where the application is located on the server, 2nd number is the amount of people aloud to connect
while (true) {
try {
// wait for a connection between 2 computers
setupStreams(); // set up a stream connection between 2 computers to communicate
whileChatting(); // send message to each other
// connect with someone and have a conversation
} catch (EOFException eofException) {
} finally {
closeChat();
}
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
//Wait for a connection then display connection information
// stream function to send and recive data
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream()); // set up pathway to send data out
output.flush(); // move data away from your machine
input = new ObjectInputStream(connection.getInputStream()); // set up pathway to allow data in
}
// this code while run during chat conversions
private void whileChatting() throws IOException {
String message = "";
do {
// have conversion while the client does not type end
try {
message = (String) input.readObject(); // stores input object message in a string variable
System.out.println("message " + message);
if (message.equals("WAIT")) {
ServerSocket server2 = new ServerSocket(5000);
System.out.println("Hello");
message = "5000";
sendMessage(message);
}
System.out.println("From server " + message);
} catch (ClassNotFoundException classnotfoundException) {
}
} while (!message.equals("CLIENT - END"));// if user types end program stops
}
private void closeChat() {
try {
output.close(); // close output stream
input.close(); // close input stream
connection.close(); // close the main socket connection
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
// send message to the client
private void sendMessage(String message) {
try {
output.writeObject(" - " + message);
output.flush(); // send all data out
} catch (IOException ioexception) {
theChatWindow.append("\n ERROR: Message cant send");
}
}
//
//
public static void main(String[] args) {
Client1 obj = new Client1();
obj.RunClient();
}
}
I can connect to the first Client i run the second client waits for ever.
Any Suggestions or comments would be appreciated.
You're blocking server cycle. You should start new thread for each connection from client. I would separate waitForConnection() from downstream code in server's loop in RunServer method. So your while loop there should look like:
public static void RunClient() {
...
while (true) {
try {
final Server srv = waitForConnection(); // wait for a connection between 2 computers
new Thread(new Runnable() {
public void run() {
try {
srv.setupStreams(); // set up a stream connection between 2 computers to communicate
srv.whileChatting(); // send message to each other
// connect with someone and have a conversation
} catch (EOFException ex) {
// ex.printStackTrace();
}
}
}).start();
} catch (EOFException eofException) {
}
}
In this case you have to make Server instance for each client and your server declaration should contain non-static props related to client like:
public class Server {
private ObjectOutputStream output; // stream data out
private ObjectInputStream input; // stream data in
private static ServerSocket server;
private Socket connection; // socket means set up connetion between 2 computers
...
And Server creation should happen inside waitForConnection() like:
private static Server waitForConnection() {
try {
Socket connection = server.accept();
return new Server(connection);
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
}
It's not the only way to do it. You may preserve Server class for being responsible for running main cycle in the same instance. But in this case I would create some additional class handling properties related to connection from particular client (connection, input, output).
This might help you think to bring it down to the essence, or it might not, I don't know really.
i
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server implements Runnable{
private final ServerSocket serverSocket;
private Socket clientBuffer;
public Server(int port) throws IOException {
this.serverSocket = new ServerSocket(port);
}
#Override
public void run() {
while(true) {
try {
if(clientBuffer != null) {
//Accept new connection and echo ip and port, as the assignment tells you to, then set clientBuffer to null and start the process again. Change Client accordingly.
}
} catch(Exception ex) {
System.err.println(ex.getMessage());
System.exit(1);
}
}
}
}
If I have a server and a client and I opened a socket between the two:
1.Is it possible that the client will have a printWriter stream, in order to write things to the socket, but the server won't have in the mean time a bufferReader?
If the answer of 1 is yes, if that client will send a message to the server (who currently doesn't have a reading stream), what will happend to this message until te server will create a reading stream and read the message?
thank you
This is not at all specific to Java, but TCP/IP. There are buffers to keep the data received, so it's not possible that some data would be lost because one end isn't "ready" yet. This is because TCP will retransmit data that hasn't been acknowledged as received, guaranteeing that all the bytes that are written are received on the other (barring obvious cases).
in addition to #Kayaman's answer:
consider this Compile-able simple Java implemented example:
Server Side:
import java.io.*;
import java.net.*;
public class SimpleServer implements Runnable{
int serverPort = 45000;
ServerSocket serverSocket = null;
boolean isStopped = false;
public SimpleServer(int port){
this.serverPort = port;
}
public void run(){
try {
serverSocket = new ServerSocket(serverPort);
} catch (IOException e) {
System.err.println("Cannot listen on this port.\n" + e.getMessage());
System.exit(1);
}
while(!isStopped){
try {
Socket clientSocket = serverSocket.accept();
} catch (IOException e) {
// do nothing
}
}
}
public static void main(String[] args) throws IOException {
SimpleServer server = new SimpleServer(45000);
new Thread(server).start();
System.out.println("Server is waiting to connect");
}
}
Client Side:
import java.io.*;
import java.net.*;
public class SimpleClient {
public static void main(String[] args) throws IOException {
Socket socket = null;
PrintWriter out = null;
try {
socket = new Socket("127.0.0.1", 45000);
out = new PrintWriter(socket.getOutputStream(), true);
System.out.println("output stream created");
out.write(9);
System.out.println("message was sent to output with no listener");
} catch (UnknownHostException e) {
// do nothing
} catch (IOException e) {
// do nothing
}
}
}
the example is an implementation of a very basic client server connection in which a socket is created and a stream is defined only on the client side, followed by a write to the stream that will eventually be read by the server (if at all).
therefore, to answer you questions:
1) yes, it's possible to open a one-way connection stream without a "listener"
2) edit: according to #EJP: It will be saved within the socket's buffer until it is read or the socket is closed.
I did my client-server application but at the moment only one user can use it. Could you help me how to make it working for more than one user. I have the following functionality: On every two minutes counter is starting to decrease. Every user have 30 seconds to connect to the application. Every connected user should see same result with which he should make some other actions. I made it by this way at the moment. The code in the different cases is not so important. I need an advice how to make it working as a structure of the code. Thanks in advance!
import java.net.*;
import java.io.*;
public class MultiServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(-1);
}
while (listening)
new MultiServerThread(serverSocket.accept()).start();
serverSocket.close();
}
}
import java.net.*;
import java.io.*;
import java.util.HashMap;
public class MultiServerThread extends Thread {
private Socket socket = null;
public MultiServerThread(Socket socket) {
super("MultiServerThread");
this.socket = socket;
}
public void run() {
try {
ObjectOutputStream toServer = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream fromServer = new ObjectInputStream(socket.getInputStream());
int userProcess = 0;
Object data = 11111;
boolean listening = true;
CountDown c = new CountDown();
int timeRemaining = 900;
while (listening) {
boolean send = true;
Object ob;
try {
ob = fromServer.readObject();
userProcess = Integer.parseInt(ob.toString());
HashMap<String,Integer> finalScores = new HashMap<String,Integer>();
if(userProcess == 0) {
timeRemaining = c.getRemainingTime();
int temp = 999;
while(timeRemaining-110>0) {
timeRemaining = c.getRemainingTime();
if(temp != timeRemaining) {
toServer.writeObject(timeRemaining-110);
toServer.flush();
temp = timeRemaining;
}
}
}
if(userProcess == 0 && timeRemaining-110 < 0) {
c = new CountDown();
send = false;
}
if(userProcess == 1) {
BoardGeneraor board = new BoardGeneraor();
data = board.getBoard();
}
if(userProcess == 2) {
int score = (Integer)fromServer.readObject();
String username = (String)fromServer.readObject();
finalScores.put(username, score);
data = finalScores;
c = new CountDown();
}
if(send) {
toServer.writeObject(data);
toServer.flush();
} else {
toServer.writeObject("quit");
toServer.flush();
}
} catch (ClassNotFoundException e) {
System.out.println(e);
}
}
fromServer.close();
toServer.close();
socket.close();
} catch(IOException e) {
System.out.println(e);
}
}
}
I think your problem is that you have confused the server and client and have put the client and server code within the same Java file. It looks like you intend MultiServerThread to be the client, since it interprets the socket's output stream as going "to server" and the socket's input stream as coming "from server." But when you create a MultiServerThread with serverSocket.accept(), you're giving it a socket that represents the server's side of the connection to one client. Thus the output stream returned by socket.getOutputStream() represents a stream from the server to the client. What MultiServerThread should actually represent is one instance of the server talking to a client, not one instance of a client connecting to the server.
In order to have clients connect to your server, you'll need a separate Java file, say Client.java, containing a separate class with a separate main method. This class should open a connection to the server with the Socket(String host, int port) constructor, and treat the input stream of that socket as a stream of input from the server. Here's a simple example:
public class Client {
public static void main(String[] args) {
Socket serverConnection = null;
try {
serverConnection = new Socket("localhost", 4444);
} catch(IOException e) {
System.err.println("Could not connect to server");
System.exit(-1);
}
try {
ObjecttInputStream fromServer = new ObjectInputStream(serverConnection.getInputStream());
Object ob = fromServer.readObject();
} catch(IOException e) {
System.err.println("Error reading from server");
}
}
}
Once you've started your server by running the MultiServer.class file, you can start a client by running the Client.class file (in a separate window, while the server is still running).