i am coding a multi client chat server.i have a server folder that contains Server.java and three client folders namely client1,client2,client3 containing java files resp.now when every client joins the server i try to send a text but the server does not picks the message.the problem is in the void run() try method. till the while(true) loop everything works.
Server code:
Chat.java
import java.net.*;
import java.io.*;
import java.util.*;
class Chat implements Runnable {
Socket skt = null;
DataInputStream dis = null;
DataOutputStream dos = null;
PrintWriter pw = null;
TreeMap<Socket, String> tm;
public Chat(Socket skt, TreeMap<Socket, String> tm) {
this.skt = skt;
this.tm = tm;
}
public void run() {
try {
dis = new DataInputStream(skt.getInputStream());
String msg = "";
while (true) {
msg = dis.readUTF();
Set s = tm.keySet();
Iterator itr = s.iterator();
while (itr.hasNext()) {
String k = (String) itr.next();
Socket v = (Socket) tm.get(k);
dos = new DataOutputStream(v.getOutputStream());
dos.writeUTF();
}
}
} catch (Exception e) {
System.out.println(e);
} finally {
try {
dis.close();
} catch (Exception ex) {
System.out.println(ex);
}
}
}
}
Server.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.TreeMap;
class Server
{
public static void main(String dt[])
{
ServerSocket sskt=null;
Socket skt=null;
DataInputStream dis=null;
DataOutputStream dos=null;
TreeMap <String,Socket>tm=new TreeMap<String,Socket>();
try
{
sskt=new ServerSocket(1234);
System.out.println("Waiting for Clients");
while(true)
{
skt=sskt.accept();
dis=new DataInputStream(skt.getInputStream());
dos=new DataOutputStream(skt.getOutputStream());
String user=dis.readUTF();
String pass=dis.readUTF();
if(user.equals(pass))
{
dos.writeBoolean(true);
tm.put(user,skt);
Chat ch=new Chat(skt,tm);
Thread t=new Thread(ch);
t.start();
}
else
{
dos.writeBoolean(false);
}
} //end of while.
}
catch(Exception e)
{
System.out.println(e);
}
finally
{
try
{
dos.close();
dis.close();
skt.close();
sskt.close();
}
catch(Exception ex)
{
System.out.println(ex);
}
}
}
}
Client Code:
Send.java
import java.io.*;
import java.net.*;
class Send implements Runnable {
Socket skt = null;
public Send(Socket skt) {
this.skt = skt;
System.out.println(skt);
}
public void run() {
InputStreamReader isrout = null;
BufferedReader brout = null;
PrintWriter pw = null;
DataInputStream dis = null;
try {
// Thread.sleep(2000);
System.out.println("Send a text");
isrout = new InputStreamReader(System.in);
brout = new BufferedReader(isrout);
pw = new PrintWriter(skt.getOutputStream(), true);
do {
String msg = brout.readLine();
pw.println(msg);
} while (!msg.equals("bye"));
} catch (Exception e) {
System.out.println(e);
} finally {
try {
pw.close();
brout.close();
isrout.close();
} catch (Exception ex) {
System.out.println(ex);
}
}
}
}
Client1.java
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;
class Client1 {
public static void main(String dt[]) {
Socket skt = null;
InputStreamReader isr = null;
BufferedReader br = null;
DataOutputStream dos = null;
DataInputStream dis = null;
try {
skt = new Socket("127.0.0.1", 1234);
System.out.println("Connected to server");
System.out.println(skt);
isr = new InputStreamReader(System.in);
br = new BufferedReader(isr);
dos = new DataOutputStream(skt.getOutputStream());
dis = new DataInputStream(skt.getInputStream());
System.out.println("Enter a username");
String user = br.readLine();
dos.writeUTF(user);
System.out.println("Enter a password");
String pass = br.readLine();
dos.writeUTF(pass);
if (dis.readBoolean()) {
System.out.println("User Authenticated");
} else {
System.out.println("Incorrect username or password");
}
Send sn = new Send(skt);
Thread t = new Thread(sn);
t.start();
} catch (Exception e) {
System.out.println(e);
} finally {
try {
// skt.close();
} catch (Exception ex) {
System.out.println(ex);
}
}
}
}
After writing any value using an outputstream you need to flush it to actually send it.
In the Chat and Server class where you use DataOutputStream, you need to call this after writing data.
dos.flush();
In the Client class after sending data through the PrintWriter you need to call this.
pw.flush();
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
Here I can solve socket programming for chat application between multiple client and server where client can send multiple message to the server. But now I want to solve a new problem where conversion of any string from any client [each client can send at most 2 messages] into a FULL UPPERCASE string with the help of the server. The server will be able to serve at most 5 clients.
This is my client coe.....
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException {
System.out.println("Client started..");
Socket socket = new Socket("127.0.0.1", 22222);
System.out.println("Client Connected..");
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
while (true) {
Scanner sc = new Scanner(System.in);
String message = sc.nextLine();
if(message.equals("exit")){
break;
}
//sent to server...
oos.writeObject(message);
try {
//receive from server..
Object fromServer = ois.readObject();
System.out.println("From Server: " + (String) fromServer);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
socket.close();
}
}
This is my server code........
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(22222);
System.out.println("Server Started..");
while (true) {
Socket socket = serverSocket.accept();
System.out.println("Client connected..");
// new Server Thread Start.....
new ServerThread(socket);
}
}
}
class ServerThread implements Runnable {
Socket clientSocket;
Thread t;
ServerThread(Socket clientSocket) {
this.clientSocket = clientSocket;
t = new Thread(this);
t.start();
}
#Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
while (true) {
//read from client...
Object cMsg = ois.readObject();
if (cMsg == null)
break;
System.out.println("From Client: " + (String) cMsg);
String serverMsg = (String) cMsg;
serverMsg = serverMsg.toUpperCase();
//send to client..
oos.writeObject(serverMsg);
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Sever side
package sockettreading;
import java.io.*;
import java.net.*;
/**
*
* #author Amanur Rahman
*/
public class SocketTreading {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(5050);
System.out.println("Server is starting...");
int cn=1;
while (cn<=5) {
Socket s = ss.accept();
System.out.println("Client"+cn+" is connected \n" + s);
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
System.out.println("Assinging new thread for this client");
Thread t = new ClientHandler(s, dis, dos);
t.start();
cn++;
}
System.out.println("Client limit cross");
ss.close();
}
}
class ClientHandler extends Thread {
final Socket soc;
final DataInputStream input;
final DataOutputStream output;
int i = 1;
public ClientHandler(Socket s, DataInputStream dis,
DataOutputStream dos) {
this.soc = s;
this.input = dis;
this.output = dos;
}
#Override
public void run() {
String received;
String ends;
String toreturn;
while (i <= 2) {
try {
output.writeUTF("Please write your message : ");
String str = input.readUTF();
System.out.println("Client msg is: "+ str.toUpperCase());
output.writeUTF("Do you want to exit or continue ( if exit type \"ENDS\" ) ");
ends = input.readUTF();
if (ends.equals("ENDS")) {
System.out.println("Client" + this.soc + "send exit.");
this.soc.close();
System.out.println("Connection closed");
break;
}
} catch (IOException e) {
System.out.println(e);
}
System.out.println("" + i);
i++;
}
try {
this.input.close();
this.output.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
// client side
package sockettreading;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
/**
*
* #author Amanur Rahman
*/
public class ClientThreading {
public static void main(String[] args) throws IOException {
try(Socket s = new Socket("localhost", 5050);){
System.out.println("Connected");
Scanner scn = new Scanner(System.in);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
DataInputStream dis = new DataInputStream(s.getInputStream());
int i = 1;
while (i <= 2) {
System.out.println(dis.readUTF());
String num1 = scn.nextLine();
dos.writeUTF(num1);
System.out.println(dis.readUTF());
String num2 = scn.nextLine();
dos.writeUTF(num2);
System.out.println(dis.readUTF());
String ends = scn.nextLine();
dos.writeUTF(ends);
if (ends.equals("ENDS")) {
System.out.println("Closing the connection" + s);
s.close();
System.out.println("Connection closed");
break;
}
i++;
}
System.out.println(dis.readUTF());
s.close();
dos.close();
dis.close();
}
catch (IOException ex) {
if(ex.getMessage()!=null){
System.out.println("Already 5 clients are served so the server is closed: ");
}else{
System.out.println("Client 2 message already send. That's way the connection closed.");
}
}
}
}
Below is my code for a simple Concurrent Server. Whenever I run multiple clients, the server only prints out the input of the first client. I'm not sure what I've done wrong. Any help would be appreciated.
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8001);
while (true){
Socket clientSocket = serverSocket.accept();
System.out.println(clientSocket);
ConcurrentServer client = new ConcurrentServer(clientSocket);
client.start();
}
} catch (IOException i){}
}
public void run(){
try {
inputStream = new BufferedReader(new InputStreamReader(concurrentSocket.getInputStream()));
outputStream = new PrintWriter(new OutputStreamWriter(concurrentSocket.getOutputStream()));
String testString = inputStream.readLine();
System.out.println(testString);
} catch (IOException i){}
}
This code might help you to understand how to run multiple clients concurrently. :)
What this code does? TCP Client sends a string to the server and TCP server sends back the string in UPPERCASE format & the server can do this concurrently with multiple connections.
I have included 3 files for the server and one more for testing the server with multiple clients(ClientTest.java)
Main.java
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
new Server(3000).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server.java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Logger;
public class Server {
private ServerSocket sSocket;
private boolean run;
private int port;
public Server(int port) throws IOException {
this.port = port;
this.sSocket = new ServerSocket(this.port);
}
public void start() {
this.run = true;
Logger.getLogger(getClass().getName()).info("Server is listening on port: " + port);
try {
while (run) {
Socket cs = sSocket.accept();
Logger.getLogger(getClass().getName())
.info("New Client Connected! " + cs.getPort());
new Thread(new Client(cs)).start(); // Put to a new thread.
}
} catch (IOException e) {
Logger.getLogger(getClass().getName()).severe(e.getMessage());
}
}
public void stop() {
this.run = false;
}
}
Client.java (Client Process on server)
import java.io.*;
import java.net.Socket;
import java.util.logging.Logger;
public class Client implements Runnable {
private Socket clientSocket;
private DataOutputStream out; // write for the client
private BufferedReader in; // read from the client
public Client(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
// Do client process
outToClient(inFromClient().toUpperCase());
closeConnection();
}
private String inFromClient() {
String messageFromClient = "";
/*
* Do not use try with resources because once -
* - it exits the block it will close your client socket too.
*/
try {
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
messageFromClient = in.readLine();
} catch (IOException e) {
Logger.getLogger(getClass().getName()).severe("InFromClientErr - " + e.getMessage());
}
return messageFromClient.trim().equals("") ? "No Inputs given!" : messageFromClient;
}
private void outToClient(String message) {
try {
out = new DataOutputStream(clientSocket.getOutputStream());
out.writeBytes(message);
} catch (IOException e) {
Logger.getLogger(getClass().getName()).severe("OutToClientErr - " + e.getMessage());
}
}
private void closeConnection() {
try {
in.close();
out.close();
clientSocket.close();
} catch (NullPointerException | IOException e) {
Logger.getLogger(getClass().getName()).severe(e.getMessage());
}
}
}
ClientTest.java (For Testing clients)
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class ClientTest {
public static void main(String[] args) {
Socket clientSocket;
try {
clientSocket = new Socket("localhost", 3000);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(new Scanner(System.in).nextLine() + '\n'); // Get user input and send.
System.out.println(inFromServer.readLine()); // Print the server response.
} catch (IOException e) {
e.printStackTrace();
}
}
}
The issue was instead with the client. Not the server. The socket was declared outside of the for loop, and therefore only one connection was being created. Like so below:
public static void main(String[] args) {
try {
socket = new Socket("127.0.0.1", 8001);
for (int i = 0; i < 5; i++){
System.out.println("Starting client: " + i);
ConcurrentClient concurrentClient = new ConcurrentClient(socket, i);
concurrentClient.run();
}
} catch (IOException io) {
}
}
The Socket should be declared inside the for loop like so:
public static void main(String[] args) {
try {
for (int i = 0; i < 5; i++){
socket = new Socket("127.0.0.1", 8001);
System.out.println("Starting client: " + i);
ConcurrentClient concurrentClient = new ConcurrentClient(socket, i);
concurrentClient.run();
}
} catch (IOException io) {
}
}
I really don't know why you need so complex structure of input and output streams. It is better to use Scanner that will wait for the new input.
Also you can use PrintWriter to output the results of your conversation.
Here is server that accepts multiple clients:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class ConcurrentServer extends Thread {
private Socket concurrentSocket;
public ConcurrentServer(Socket clientSocket) {
this.concurrentSocket = clientSocket;
}
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8001);
while (true){
Socket clientSocket = serverSocket.accept();
System.out.println(clientSocket);
ConcurrentServer client = new ConcurrentServer(clientSocket);
client.start();
}
} catch (IOException i){}
}
public void run(){
try {
InputStream inputStream = concurrentSocket.getInputStream();
Scanner scanner = new Scanner(inputStream);
OutputStream outputStream = concurrentSocket.getOutputStream();
PrintWriter pw = new PrintWriter(outputStream);
while(scanner.hasNextLine()){
String line = scanner.nextLine();
System.out.println(line);
pw.println("message: " + line);
pw.flush();
}
} catch (IOException i){}
}
}
does anyone know whats wrong with my code?
When I write something with client1 i just see it on the server and on the client1 but not on client2.
run() in Client.java:
public void run() {
Scanner input = new Scanner(System.in);
try {
Socket client = new Socket(host, port);
System.out.println("client started");
OutputStream out = client.getOutputStream();
PrintWriter writer = new PrintWriter(out);
InputStream in = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String i = input.nextLine();
writer.write(clientname + ": " + i + newline);
writer.flush();
String s = null;
while((s = reader.readLine()) != null) {
System.out.println(s);
}
writer.close();
reader.close();
client.close();
}
If you need the Server code or anything else just ask.
Thanks in advance!!
Additionally the Server:
public class Server {
public static void main(String[] args) {
int port = 40480;
int max = 10;
ExecutorService executor = Executors.newFixedThreadPool(max);
try {
ServerSocket server = new ServerSocket(port);
System.out.print("server started" + "\n");
while(true) {
try {
Socket client = server.accept();
executor.execute(new Handler(client));
}
catch (IOException e) {
e.printStackTrace();
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
And the Handler:
public class Handler implements Runnable{
private Socket client;
public Handler(Socket client) {
this.client = client;
}
#Override
public void run() {
try {
OutputStream out = client.getOutputStream();
PrintWriter writer = new PrintWriter(out);
InputStream in = client.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String s = null;
while((s = reader.readLine()) != null) {
writer.write(s + "\n");
writer.flush();
System.out.println(s);
}
writer.close();
reader.close();
client.close();
}
catch(Exception e) {
}
}
}
This is an example - it is not complete but should give you an idea how you could multicast output to a number of listening clients. There are better ways to do this, but I wrote it similar to how you appeared to be doing the sockets. It also lacks error checking in many places and I have left that as an exercise for the reader. This code was also written so that it can be used on Java 1.6 or higher.
The code uses a list of connected Clients maintained in the Server object. When input is received from one client, the output is multicast to each client in the Client list. Writing is done via a write method in the Client class.
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.LinkedList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MulticastEchoServer {
List<Client> clientList = new LinkedList<Client>();
ExecutorService executor;
int port = 40480;
int max = 10;
public MulticastEchoServer() {
this.executor = Executors.newFixedThreadPool(max);
}
public void writeToAllClients(String string) throws IOException {
// Multiple threads access this so it must be in synchronized block
synchronized (this.clientList) {
Iterator<Client> iter = this.clientList.iterator();
while (iter.hasNext())
iter.next().write(string);
}
}
public void addClient(Client client) {
// Multiple threads access this so it must be in synchronized block
synchronized (this.clientList) {
clientList.add(client);
}
}
public void removeClient(Client client) {
// Multiple threads access this so it must be in synchronized block
synchronized (this.clientList) {
clientList.remove(client);
}
}
public void listen() {
try {
ServerSocket server = new ServerSocket(port);
System.out.println("server started and listening for connections");
while (true) {
try {
Socket socket = server.accept();
System.out.print("connection accepted" + "\n");
Client newClient = new Client(this, socket);
this.addClient(newClient);
this.executor.execute(newClient);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new MulticastEchoServer().listen();
}
private class Client implements Runnable {
Socket socket;
PrintWriter writer;
BufferedReader reader;
MulticastEchoServer server;
public Client(MulticastEchoServer server, Socket socket) throws IOException {
this.server = server;
this.socket = socket;
this.writer = new PrintWriter(this.socket.getOutputStream());
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
synchronized public void write(String string) throws IOException {
writer.write(string);
writer.flush();
}
public void close() {
this.writer.close();
try {
this.reader.close();
} catch (IOException e) {
}
try {
this.socket.close();
} catch (IOException e) {
}
}
#Override
public void run() {
System.out.println("Client Waiting");
String inString = null;
try {
while ((inString = this.reader.readLine()) != null) {
this.server.writeToAllClients(inString + "\n");
System.out.println(inString);
}
} catch (IOException e1) {
}
server.removeClient(this);
this.close();
System.out.println("Client Closed");
}
}
}
In your handler:
while((s = reader.readLine()) != null) {
writer.write(s + "\n");
writer.flush();
System.out.println(s);
}
You are only writing the string back to the sender, not to all connected sockets
I tried to send message from server to client but if i send message the client needs to connect again or println again...
So how does it work?
I tried to println again from server to client but the client wont receive it.
So how to send message to a specific client at any time.
Server:
package server.server.com;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.ArrayList;
public class Server extends Thread {
private static ServerSocket serverSocket;
public static Socket clientSocket;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
static InputStream is;
static OutputStream os;
static byte[] buf;
static BufferedReader reader;
static BufferedWriter writer;
static double ConsoleMessage;
public static String output;
static BufferedReader bufferedReader2;
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(12345);
} catch (IOException e) {
System.out.println("Could not listen on port: 12345");
}
System.out.println("Server started. Listening to the port 12345");
while (true) {
try {
clientSocket = serverSocket.accept();
inputStreamReader = new InputStreamReader(
clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
InputStream inputStream = new ByteArrayInputStream(
bufferedReader.readLine().getBytes(
Charset.forName("UTF-8")));
bufferedReader2 = new BufferedReader(new InputStreamReader(
inputStream));
output = bufferedReader2.readLine();
System.out.println(output);
out.flush();
out.close();
inputStreamReader.close();
clientSocket.close();
} catch (IOException ex) {
System.out.println("Problem in message reading");
}
}
}
}
Client:
client = new Socket();
client.connect(
new InetSocketAddress(
"IP-ADDRESS",
PORT),
5000);
in = new BufferedReader(
new InputStreamReader(
client.getInputStream()));
printlng = new PrintWriter(
client.getOutputStream());
printlng.println(mLongitude);
printlng.flush();
try {
if ((Response = in
.readLine()) != null) {
....
You should take a look at http://developer.android.com/google/gcm/index.html. Maybe you could take advantage of push notifications in your app.
Maybe you can do something like this
Server:
private boolean sendMessage(final String msg, final String dstIp, final int dstPort) {
DatagramSocket sendSocket = null;
try {
sendSocket = new DatagramSocket();
final InetAddress local = InetAddress.getByName(dstIp);
final int msg_length = msg.length();
final byte[] message1 = msg.getBytes();
final DatagramPacket sendPacket = new DatagramPacket(message1,
msg_length, local, dstPort);
sendSocket.send(sendPacket);
} catch (final Exception e) {
e.printStackTrace();
return false;
} finally {
if (sendSocket != null) {
sendSocket.disconnect();
sendSocket.close();
sendSocket = null;
}
}
return true;
}
Client:
public static void receiveMessage() {
if ((socket == null) || socket.isClosed()) {
socket = new DatagramSocket(BROADCAST_PORT);
socket.setSoTimeout(5000);
}
try {
idMsgs.clear();
while ((socket != null) && !socket.isClosed()) {
socket.setReuseAddress(true);
socket.setSoTimeout(10000);
try {
final byte[] receiveBuffer = new byte[sizepck];
final DatagramPacket packet = new DatagramPacket(
receiveBuffer, receiveBuffer.length);
socket.receive(packet);
} catch (final SocketTimeoutException e) {
} catch (final Throwable e) {
}
}
} catch (final Throwable e1) {
try {
Thread.sleep(TIME_RETRY);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
finally {
if (socket != null) {
socket.close();
}
}
}
I've been trying this for a while, and I want multiple clients to recieve multiple inputs simultaneously. There is one problem, I want the server to print "Hi" to all clients if one client says 'print2all Hi'.
I know how to process it to print it, just to print to ALL clients is the problem.
Here's what I have so far.
Server
try{
try{
server = new ServerSocket(25565);
} catch (Exception e){
e.printStackTrace();
}
while (isListening){
new SocketThread(server.accept()).start();
}
server.close();
} catch (Exception e){
e.printStackTrace();
}
SocketThread
try {
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine, outputLine;
Processor kkp = new Processor();
out.println("Hi!");
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.Proccess(inputLine,this.socket);
out.println(outputLine);
}
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
Client
Processor p = new Processor();
socket = new Socket("localhost",25565);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
out.println("print2all Hi")
socket.close();
First you need to keep track of all connected clients:
final List<SocketThread> clients = new ArrayList<>();
while (isListening){
SocketThread client = new SocketThread(server.accept()).start();
clients.add(client);
}
Having such list if one client receives "print2all Hi" it simply iterates over all clients and sends message to each of them. To do this you'll most likely have to expose some method on SocketThread that will access client socket. This means you'll have to change out variable to field.
Alternative approach is to keep a list of client sockets. But this breaks encapsulation badly. Also you might run into nasty IO/thread-safety issues if sockets are exposed directly. Better hide them behind some API (like SocketThread method) and do the synchronization properly inside.
A full implementation of what you are looking.
Server
package tcpserver;
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.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TCPServer {
private int serverPort = 25565;
private ServerSocket serverSocket;
private List<ConnectionService> connections = new ArrayList<ConnectionService>();
public TCPServer() {
try {
serverSocket = new ServerSocket(serverPort);
System.out.println("Waiting...");
while (true) {
Socket socket = serverSocket.accept();
System.out.println("Connected: " + socket);
ConnectionService service = new ConnectionService(socket);
service.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new TCPServer();
}
class ConnectionService extends Thread {
private Socket socket;
private BufferedReader inputReader;
private PrintWriter outputWriter;
//private String username;
public ConnectionService(Socket socket) {
this.socket = socket;
try {
inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
outputWriter = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
#Override
public void run() {
while (true) {
try {
String receivedMessage = inputReader.readLine();
System.out.println(receivedMessage);
StringTokenizer stoken = new StringTokenizer(receivedMessage);
String fargument = stoken.nextToken();
if (fargument.equals("print2all")) {
this.sendToAnyone(stoken.nextToken());
}
} catch (IOException ex) {
Logger.getLogger(TCPServer.class.getName()).log(Level.SEVERE, null, ex);
} catch (NullPointerException e) {
System.out.println(e.getMessage());
} finally {
outputWriter.close();
}
}
}
protected void sendMessage(String message) {
outputWriter.println(message);
}
private void sendToAnyone(String message) {
for (ConnectionService connection : connections) {
connection.sendMessage(message);
}
}
}
}
Client
package tcpclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class tcpClient extends javax.swing.JFrame {
private Socket socket;
private BufferedReader inputReader;
private PrintWriter outputWriter;
public tcpClient() {
connectToServer();
}
private void connectToServer() {
try {
socket = new Socket(InetAddress.getByName("localhost"), 25565);
inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
outputWriter = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
e.printStackTrace();
}
new Thread() {
#Override
public void run() {
receiveData();
}
}.start();
}
private void receiveData() {
try {
while (true) {
System.out.println(inputReader.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendData(String messageToSend) {
outputWriter.println(messageToSend);
}
public void closeSocket() {
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
tcpClient client = new tcpClient();
client.sendData("print2all Hi");
client.closeSocket();
}
});
}
}