I have 2 classes
public class ServerStart implements Runnable
{
#Override
public void run()
{
try
{
serverSock = new ServerSocket(2101);
while (true)
{
sock = serverSock.accept();
System.out.println(sock);
clients.put(sock.getPort(),sock);
HandleMultipleClients hmc=new HandleMultipleClients();
hmc.messagetospecificclients(String ipaddress,String choice)
}
2nd class is
public class HandleMultipleClients
{
Socket soc;
ServerSocket serverSock;
DataOutputStream dos;
DataInputStream dis;
public HandleMultipleClients()
{
}
public void messagetospecificclients(String ipaddress,String choice) throws IOException, InterruptedException
{
System.out.print(ipaddress+"\n"+choice);
for (Iterator<Integer> iter = clients.keySet().iterator(); iter.hasNext(); )
{
System.out.print("ok1");
int key = iter.next();
java.net.Socket client = clients.get(key);
InetAddress zee = client.getInetAddress();
String s = zee.getHostAddress();
System.out.print(s);
if (zee.getHostAddress().equals(ipaddress))
{
System.out.print("ok2");
dos =new DataOutputStream(client.getOutputStream());
dos.writeUTF(choice);
}
How can i get through for loop of 2nd class function i.e messagetospecificclients(String ipaddress,String choice) when i am adding clients to the first class kindly help me. My code should be like that i should add the clients to first class and should traverse the for loop in 2nd class
I would restructure the code. Separate the code for the mechanics for the socket server and the manipulation of the return data. The return data code can be launched from messageToSpecificClient method. You could launch a whole class or whatever just from that.
I have not run this, but it should run.
Another caveat about this code is that it will have issues with some unicode.
So if that is in your requirements that will need to be changed some.
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MultiThreadServer implements Runnable
{
Socket csocket;
MultiThreadServer(Socket csocket)
{
this.csocket = csocket;
}
public static void main(String args[]) throws Exception
{
ServerSocket ssock = new ServerSocket(1234);
System.out.println("Listening");
while (true)
{
Socket sock = ssock.accept();
System.out.println("Connected");
new Thread(new MultiThreadServer(sock)).start();
}
}
public void run()
{
PrintStream pstream = null;
InputStream input = null;
try
{
pstream = new PrintStream(csocket.getOutputStream());
input = csocket.getInputStream();
String stringFromClient = readFromInputStream(input);
String response = messageTosSpecificClients(stringFromClient);
pstream.write(response.getBytes());
}
catch (IOException e)
{
System.out.println(e);
}
finally
{
if (pstream != null)
try
{
pstream.close();
}
catch (Throwable t)
{
}
if (input != null)
try
{
input.close();
}
catch (Throwable t)
{
}
if (csocket != null)
try
{
csocket.close();
}
catch (Throwable t)
{
}
}
}
String readFromInputStream(InputStream inputStream) throws IOException
{
int ch;
StringBuilder sb = new StringBuilder();
while ((ch = inputStream.read()) != -1)
sb.append((char) ch);
return sb.toString();
}
public String messageTosSpecificClients(String choice) throws IOException
{
String ipaddress = "127.0.0.1";
String retData = "General Return String";
System.out.print(ipaddress + "\n" + choice);
InetAddress zee = csocket.getInetAddress();
String s = zee.getHostAddress();
System.out.print(s);
if (zee.getHostAddress().equals(ipaddress))
{
retData = "Specific Return String";
}
return retData;
}
}
Related
I'm coding socket client in Java.
In the program, I want to get information from server.
When the server receives "GET_LIGHTS" command, it sends back data in JSON format.
But in my code, bw.write() and bw.flush() doesn't work before socket.close().
So, the BufferedReader object is not ready: br.ready() returns false.
Is there any mistake in my code?
The client code is shown bellow.
package monitor;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
public class SocketClient {
static private int port;
static private String hostName;
private Socket socket;
public SocketClient(String host, int port) {
this.hostName = host;
this.port = port;
}
// get lights by JSON
public void getLights() {
try {
// generate socket
InetSocketAddress endpoint = new InetSocketAddress(hostName, port);
socket = new Socket();
socket.connect(endpoint);
// setting
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
BufferedWriter bw = new BufferedWriter(out);
InputStreamReader in = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(in);
// send command
bw.write("GET_LIGHTS");
bw.flush();
// receive message from server
System.out.println(br.readLine());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void initLights(ArrayList<Light> lights) {
getLights();
}
}
Edited:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class SocketServer extends Thread{
static final int PORT = 44344;
static private ILS ils;
private ServerSocket serverSocket;
private Socket socket;
public SocketServer(ILS ils) {
this.ils = ils;
}
#Override
public void run() {
serverSocket = null;
System.out.println("Server: listening");
try {
serverSocket = new ServerSocket(PORT);
while(true){
socket = serverSocket.accept();
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
ArrayList<String> cmd = new ArrayList<>();
String in;
while( (in = br.readLine()) != null ){
cmd.add(in);
}
command(cmd);
if( socket != null){
socket.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
if( serverSocket != null){
try {
serverSocket.close();
serverSocket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
// send message to client
private void sendMessage(String str) {
System.out.println(str);
try {
OutputStream output = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(output));
bw.write(str + "¥n");
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// error
private void printError(String err) {
String str = "ERROR; ";
str += err;
sendMessage(str);
}
public void command(ArrayList<String> cmd) {
String mode = cmd.get(0);
if(mode == null){
}else switch(mode){
case "MANUAL_SIG-ALL":
System.out.println("全照明一括 信号値指定調光");
manualSigAll(cmd.get(1));
break;
case "MANUAL_SIG-INDIVIDUAL":
System.out.println("全照明独立 信号値指定調光");
manualSigIndividual(cmd.get(1));
break;
case "MANUAL_ID-SIG":
System.out.println("照明ID・信号値指定調光");
manualIDSig(cmd.get(1));
break;
case "MANUAL_ID-RELATIVE":
System.out.println("照明ID・相対信号値指定調光");
break;
case "DOWNLIGHT_ALL":
System.out.println("Downlight: All Control");
downlightAll(cmd.get(1));
break;
case "DOWNLIGHT_INDIVIDUAL":
System.out.println("Downlight: Individual control");
downlightIndividual(cmd.get(1));
break;
case "GET_LIGHTS":
System.out.println("Sending lights via JSON");
sendLights();
break;
default:
System.out.println("Error: 不明なmode command");
}
}
// 全照明一括 信号値指定調光
private void manualSigAll(String sigs) {
if(sigs == null) {
System.out.println("信号値のフォーマットを確認してください");
} else {
ArrayList<Integer> s = new ArrayList<>();
String[] buf = sigs.split(",");
for(String i:buf) s.add(Integer.parseInt(i));
for(Light l: ils.getLights()) {
l.setLumPct((double)s.get(0)/255.0*100.0);
l.setSignal(s.get(0), s.get(1));
}
}
// 調光
ils.downlightDimmer.send();
}
// 全照明独立 信号値指定調光
private void manualSigIndividual(String sigs) {
if(sigs == null) {
System.out.println("信号値のフォーマットを確認してください");
} else {
ArrayList<Integer> s = new ArrayList<>();
String[] buf = sigs.split(",");
for(String i:buf) s.add(Integer.parseInt(i));
for(int i=0; i<ils.getLights().size(); i++) {
ils.getLights().get(i).setSignal(s.get(0), s.get(1));
s.remove(0);
s.remove(0);
}
}
ils.downlightDimmer.send();
}
// 照明ID・信号値指定調光
private void manualIDSig(String sigs) {
if(sigs == null) {
System.out.println("信号値のフォーマットを確認してください");
} else {
ArrayList<Integer> s = new ArrayList<>();
String[] buf = sigs.split(",");
for(String i:buf) s.add(Integer.parseInt(i));
System.out.println(s.get(0));
ils.getLight(s.get(0)).setSignal(s.get(1), s.get(2));
}
ils.downlightDimmer.send();
}
private void downlightAll(String cmd) {
if(cmd == null) {
printError("Check for data command.");
} else {
ArrayList<Double> data = new ArrayList<>();
String[] buf = cmd.split(",");
for(String i:buf) data.add(Double.parseDouble(i));
for(Light l: ils.getLights()) {
l.setLumPct(data.get(0));
l.setTemperature(data.get(1));
}
}
// dimming
ils.downlightDimmer.send();
}
private void downlightIndividual(String cmd) {
if(cmd == null) {
printError("Check for data command.");
} else {
ArrayList<Integer> id = new ArrayList<>();
ArrayList<Double> lumPct = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
String[] buf = cmd.split(",");
if(buf.length % 3 != 0) {printError("invalid number of data.");}
for(int i=0; i<buf.length/3; i++) {
int n = i*3;
try {
id.add(Integer.parseInt(buf[n]));
lumPct.add(Double.parseDouble(buf[n + 1]));
temp.add(Integer.parseInt(buf[n + 2]));
} catch (Exception e) {
printError(e.getMessage());
return;
}
}
while (id.size() > 0) {
// update light object
Light light = ils.getLight(id.get(0));
light.setLumPct(lumPct.get(0));
light.setTemperature(temp.get(0));
// remove data from array list
id.remove(0);
lumPct.remove(0);
temp.remove(0);
}
// dimming
ils.downlightDimmer.send();
}
}
private void sendLights() {
ObjectMapper mapper = new ObjectMapper();
String json = "";
try {
json = mapper.writeValueAsString(ils.getLights());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// output
sendMessage(json);
}
}
If your server is using readLine(), as is probable, it will block until you close the connection, because you aren't sending a line.
Add bw.newLine() before the flush().
EDIT As predicted, your server isn't sending lines, so it needs the same treatment as above. However there is an anterior problem:
while( (in = br.readLine()) != null ){
cmd.add(in);
}
This loop in the server cannot possibly exit until the client closes the connection. You should process a line at a time in the server, or else moderate your expectations of the client's behaviour.
I've got a Client and a Server. The client simply sends 1 line of input to the server and then prints the response.
I'm getting a
SocketException (Software caused connection abort: recv failed)
[...]
at java.io.InputStreamReader.read(InputStreamReader.java:168)
at hw3.Client.readLine(Client.java:37)
at hw3.Client.main(Client.java:28)
The debugger tells me that the socket is not closed at the time of the read, what else can cause this exception?
I think I'm running into issues because of the threading, does anything stick out as "doing it wrong"?
public class Client
{
public static final int PORT = ReversingEchoServerDispatcher.PORT;
private static final String host = "localhost";
private static Socket sock;
public static void main(String[] args)
throws IOException
{
try(Socket sock = new Socket(host, PORT);
InputStreamReader clin = new InputStreamReader(sock.getInputStream());
OutputStream clout = sock.getOutputStream();
Scanner sc = new Scanner(System.in))
{
Client.sock = sock;
byte[] cl = sc.nextLine().getBytes("UTF-8");
clout.write(cl);
System.out.println(readLine(clin));
}
}
private static String readLine(InputStreamReader in)
throws IOException
{
StringBuilder sb = new StringBuilder();
for(int i = in.read(); i != -1; i = in.read())
{
char c = (char) i;
if(c != '\n') sb.append(c);
else break;
}
return sb.toString();
}
}
public class ServerDispatcher
{
public static final int PORT = 8034;
public static void main(String[] args)
{
try (ServerSocket serversock = new ServerSocket(PORT))
{
while(true)
{
Socket socket = serversock.accept();
ServerLogic sv = new ServerLogic(socket);
new Thread(() -> {
try {
sv.run();
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
}).start();
}
}
catch(IOException e)
{
e.printStackTrace(System.err);
}
}
}
For the record, the ServerLogic class looks something like the following. My exit code is 1, not -999, so it's not that socket.close() is failing
class ServerLogic
{
Socket socket;
public
ServerLogic(Socket s)
{
this.socket = s;
}
public void run()
throws IOException
{
try(InputStreamReader in = new InputStreamReader(socket.getInputStream());
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream()))
{
StringBuilder sb = new StringBuilder();
while(in.ready()) {
char c = (char) in.read();
if(c == '\n') {
String str = process(sb);
if(str != null) out.write(str);
else return;
} else {
sb.append(in.read());
}
}
} finally {
try {
socket.close();
} catch(IOException ex) {
ex.printStackTrace(System.err);
System.exit(-999);
}
}
}
private static String process(StringBuilder sb)
{ /* ... */ }
The server is expecting a newline \n to terminate the input but you never send one from the client. sc.nextLine() returns the input line but does not include the terminating newline. The while(in.ready()) loop eventually ends and the server closes the socket without ever sending a response.
Good day, I'm trying to create a Client/Server chat, that the 1st client send message to server and the server send it to client 2 and vice versa, but the server is just receiving from 1st client only and not from 2nd.
and also, how can i send messages from client 1 to 2 & vice versa
package s;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
public class Client
{
public static void main(String[] args) throws IOException, Throwable
{
Socket s;
BufferedReader in;
PrintWriter out;
Scanner sc = new Scanner(System.in);
s = new Socket(InetAddress.getLocalHost(),9000);
System.out.println("Connection pending");
in = new BufferedReader (new InputStreamReader(s.getInputStream()));
out = new PrintWriter(s.getOutputStream());
String msg = in.readLine();
System.out.println(msg);
while(msg!="")
{
msg = sc.nextLine();
out.println(msg+"\n");
out.flush();
}
s.close();
sc.close();
}
}
=============================================
package s;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class TClient extends Thread
{
private int num;
private Socket s;
private BufferedReader in;
private PrintWriter out;
public Socket getS()
{
return s;
}
public BufferedReader getIn()
{
return in;
}
public PrintWriter getOut()
{
return out;
}
public TClient(Socket s,int num) throws IOException
{
this.s = s;
this.setNum(num);
System.out.println("Client"+num);
out = new PrintWriter(s.getOutputStream());
in = new BufferedReader (new InputStreamReader(s.getInputStream()));
out.println("Connected"+num+"\n");
out.flush();
}
public void run()
{
while(true)
{
try
{
String msg="";
msg = in.readLine();
System.out.println(msg);
if (msg.equals(".")) break;
}
catch (IOException e)
{
}
}
try
{
s.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public int getNum()
{
return num;
}
public void setNum(int num)
{
this.num = num;
}
}
========================================================
package s;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server
{
public static void main(String[] args)
{
ServerSocket ss ;
Socket s = null ;
int nb_clients = 0;
String msg = "";
TClient[] connexions = new TClient[2];
try
{
ss = new ServerSocket(9000);
System.out.println("Server is listening in:"+ss.getLocalPort());
boolean continu = false;
while(!continu)
{
s = ss.accept();
connexions[nb_clients] = new TClient(s,nb_clients+1);
connexions[nb_clients].start();
nb_clients++;
if (nb_clients>=2) continu=true;
}
System.out.println("Clients connected");
s.close();
ss.close();
}
catch(IOException e)
{
}
}
}
========================================
and the output of each terminal is :
Server is listening in:9000
Client1
Client2
Clients connected
and the output of the 2 clients are :
Connection pending
Connected1
Connection pending
Connected2
if i write a message from 1 & 2 to the server, the server output will be like this:
Server is listening in:9000
Client1
Client2
Clients connected
111111111111111111111111111111111111
================================================================
UPDATE :
i changed a condition in server
if (nb_clients>2) continu=true;
and now i can recieve from both clients, now i have to know how i make them communicate between the clients
Solution for two clients.
Sending messages from one client to another client.
The server will have to marshall the messages between the clients.
public class Server
{
static TClient[] connexions = new TClient[2];
public static void send(int clientNum, String message) {
TClient t = connexions[clientNum];
if(t != null) {
t.getOut().println(message);
t.getOut().flush();
}
}
}
In TClient added:
public void sendMessage(String message) {
int client = (getNum()-1)==1 ? 0:1;
Server.send(client, message);
System.out.printf("Sending message(%s) to client:%d from client:%d%n",message,client,getNum());
}
which I added a call to inside your while loop.
In Client I used another thread for receiving message from the server called ReceiveMessageThread:
public class Client
{
public static void main(String[] args) throws IOException, Throwable
{
Socket s;
BufferedReader in;
PrintWriter out;
Scanner sc = new Scanner(System.in);
s = new Socket(InetAddress.getLocalHost(), 9000);
System.out.println("Connection pending");
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new PrintWriter(s.getOutputStream());
ReceiveMessageThread thread = new ReceiveMessageThread(in);
String msg = in.readLine();
System.out.println(msg);
thread.start();
while (msg != "")
{
msg = sc.nextLine();
out.println(msg + "\n");
out.flush();
}
s.close();
sc.close();
}
public static class ReceiveMessageThread extends Thread
{
private BufferedReader in;
public ReceiveMessageThread(BufferedReader in)
{
this.in = in;
}
public void run()
{
while (true)
{
try
{
String message = readMessage(in);
if (message != null && !message.equals(""))
System.out.println(message);
} catch (IOException ie)
{
ie.printStackTrace();
}
}
}
public String readMessage(BufferedReader in) throws IOException
{
String msgreceived = "";
String readValue = "";
while (in.ready())
{
readValue = in.readLine();
if (readValue != null)
msgreceived += readValue;
}
return msgreceived;
}
}
}
in server i changed :
if (nb_clients>2) continu=true;
and the server reads from different clients.
I want to write a simple server that listens on a port and spawns new threads for handling new connections.
I attempted to use try-with-resources for accepting new connections but failed because sockets in child threads seem to be closed immediately and I don't understand why.
Here are 2 simplified examples.
a) The working example of the server (without try-with-resources):
package MyTest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServerA implements Runnable {
private int port;
private ServerSocket serverSocket;
public MyServerA(Integer port) {
this.port = port;
}
#Override
public void run() {
try {
serverSocket = new ServerSocket(port);
} catch(IOException ioe) {
System.err.println("error opening socket. " + ioe.getStackTrace());
}
while (true) {
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
ClientServiceThread cliThread = new ClientServiceThread(clientSocket);
cliThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ClientServiceThread extends Thread {
private Socket s;
boolean goOn = true;
ClientServiceThread(Socket s) {
this.s = s;
}
public void run() {
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(this.s.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(this.s.getOutputStream()));
while (goOn) {
final String req = in.readLine();
if (req != null) {
System.out.println("got: " + req);
out.println("you said: " + req);
out.flush();
if (req.contains("bye")) {
System.out.println("closing thread");
goOn = false;
}
}
}
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyServerA a = new MyServerA(30000);
a.run();
}
}
b) Exactly the same, but with try-with-resources (doesn't work):
package MyTest;
import java.io.BufferedReader;
public class MyServerB implements Runnable {
private int port;
private ServerSocket serverSocket;
public MyServerB(Integer port) {
this.port = port;
}
#Override
public void run() {
try {
serverSocket = new ServerSocket(port);
} catch(IOException ioe) {
System.err.println("error opening socket. " + ioe.getStackTrace());
}
while (true) {
try (Socket clientSocket = serverSocket.accept();) {
ClientServiceThread cliThread = new ClientServiceThread(clientSocket);
cliThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ClientServiceThread extends Thread {
private Socket s;
boolean goOn = true;
ClientServiceThread(Socket s) {
this.s = s;
}
public void run() {
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(this.s.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(this.s.getOutputStream()));
while (goOn) {
final String req = in.readLine();
if (req != null) {
System.out.println("got: " + req);
out.println("you said: " + req);
out.flush();
if (req.contains("bye")) {
System.out.println("closing thread");
goOn = false;
}
}
}
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyServerB b = new MyServerB(30000);
b.run();
}
}
The example in a) works like expected.
The example in b) accepts a connection but closes it immediately.
Can someone explain to me why and tell me how I do this properly?
The structure
try (resource = ...) {
}
is equivalent to
resource = null;
try {
resource = ...;
} finally {
if (resource != null) {
resource.close();
}
}
That's it. It is just a syntactic sugar, just shorter way to write the same. So, when you put statement Socket clientSocket = serverSocket.accept(); into try-with-resource block you actually close it once you leave the block.
This structure is good when processing of stream is done synchronously, i.e. when you open stream, read or write and close it.
In your case you get the stream and process it in separate thread and therefore cannot close it immediately. Client should decide to close the stream itself. For example when user press button "disconnect" or when server sends special application level command "close connection" or if IOException is thrown.
I am working on multi chat in java. I'm kinda new to this socket thing.
There is a problem with my code but I can't find it. I think the problem is in clientSocket.getInputStream(); . I inserted System.out.println before and after this statement. I can't see the second one. It seems that client can connect to port but cannot get inputs from server. If you can help me, I really would be thankful. It has been 3 hours but still I can't find the problem
ClientSide.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientSide
{
public Socket clientSocket;
public ObjectOutputStream outStream;
public ObjectInputStream inStream;
public String receiveMessage=null,sendMessage=null;
public GuiScreen gui;
public void run()
{
try
{
clientSocket = new Socket("localhost", 2222);
inStream = new ObjectInputStream(clientSocket.getInputStream());
outStream = new ObjectOutputStream(clientSocket.getOutputStream());
outStream.flush();
while(true)
{
try
{
receiveMessage = (String)inStream.readObject();
gui.appendMessage(receiveMessage);
}
catch(ClassNotFoundException classNot)
{System.err.println("data received in unknown format");}
}
}
catch(UnknownHostException unknownHost)
{System.err.println("You are trying to connect to an unknown host!");}
catch(IOException ioException)
{ioException.printStackTrace();}
}
public String readMessage()
{
String text = "";
try
{
text = (String)inStream.readObject();
}
catch (ClassNotFoundException | IOException e)
{e.printStackTrace();}
return text;
}
public void sendMessage(String msg)
{
try
{
outStream.writeObject(msg);
outStream.flush();
}
catch(IOException ioException){ioException.printStackTrace();}
}
public ClientSide()
{}
private void showGui()
{
gui = new GuiScreen(this,"Client Side");
}
public static void main(String[] args)
{
ClientSide client = new ClientSide();
client.showGui();
client.run();
}
}
MultiCheatServer.java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MultiChatServer
{
public static ClientThread[] clientThreads = new ClientThread[10];
public static int portNumber = 2222;
public static ServerSocket serverSocket = null;
public static Socket clientSocket = null;
public static void openPort()
{
try
{
serverSocket = new ServerSocket(portNumber);
}
catch (IOException e)
{e.printStackTrace();}
}
public static void connectToClients()
{
while(true)
{
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{e.printStackTrace();}
for(int i = 0; i<=9; ++i)
{
if(clientThreads[i] == null)
{
clientThreads[i] = new ClientThread(clientSocket,clientThreads);
clientThreads[i].start();
break;
}
}
}
}
public static void main(String[] args)
{
openPort();
connectToClients();
}
}
ClientThread.java
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.net.Socket;
public class ClientThread extends Thread
{
public ObjectInputStream inStream = null;
public ObjectOutputStream outStream = null;
public Socket clientSocket;
public ClientThread[] clientThreads;
public ClientThread (Socket cSocket,ClientThread[] cThreads)
{
clientSocket = cSocket;
clientThreads = cThreads;
}
public void sendMessage(String msg)
{
try
{
outStream.writeObject(msg);
outStream.flush();
}
catch (IOException e)
{e.printStackTrace();}
}
public String readMessage()
{
String text = null;
try
{
text = (String)inStream.readObject();
}
catch (ClassNotFoundException | IOException e)
{e.printStackTrace();}
return text;
}
public void run()
{
String text;
String name;
try
{
inStream = new ObjectInputStream(clientSocket.getInputStream());
outStream= new ObjectOutputStream(clientSocket.getOutputStream());
outStream.flush();
sendMessage("Name:\n");
name = readMessage().trim();
sendMessage("type /quit if you want to quit\n");
for(int i = 0 ; i <=9 ; ++i)
if(clientThreads[i]!=null && clientThreads[i]!=this)
clientThreads[i].sendMessage(name + "has come\n");
while(true)
{
text = readMessage() ;
if(text.startsWith("/quit"))
break;
for(int i = 0; i<=9; ++i)
if(clientThreads[i] != null)
clientThreads[i].sendMessage("<" + name + ">" + text);
}
for(int i = 0 ;i<=9; ++i)
if(clientThreads[i]!=null && clientThreads[i]!=this)
clientThreads[i].sendMessage(name + " has disconnected\n");
sendMessage("Bye\n");
inStream.close();
outStream.close();
for(int i = 0;i<=9;++i)
if(clientThreads[i]==this)
clientThreads[i] = null;
}
catch (IOException e)
{e.printStackTrace();}
}
}
One problem I see is that you have to decide who creates the input stream first, the server or the client.
ObjectInputStream tries to read a serialization header in its constructor, and if the output stream has not written it yet it will wait. Now both client and server are waiting for the other to "speak" first.