how to connect one server to multple clients - java

I have done one server and one client communication by using ip address but am stuck with one server multiple communication
s=new ServerSocket(77);
ss=s.accept();
icon.displayMessage("New message for you", "Please click here", TrayIcon.MessageType.WARNING);
os=ss.getOutputStream();
ps=new PrintStream(os);
is=ss.getInputStream();
br=new BufferedReader(new InputStreamReader(is));
ps.println(st);
}
catch(Exception e)
{}
on client side
try
{
ss=new Socket(ip,77);
}
catch(Exception e){
}
is=ss.getInputStream();
br=new BufferedReader(new InputStreamReader(is));
os=ss.getOutputStream();
ps=new PrintStream(os);
ps.println(msg+" : "+st1);

you should run each session in a separate Thread, like this:
static class Session extends Thread {
Socket s;
Session(Socket s) {
this.s = s;
}
#Override
public void run() {
try {
OutputStream os = s.getOutputStream();
// your code
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) throws Exception {
ServerSocket s = new ServerSocket(77);
for (;;) {
Socket ss = s.accept();
new Session(ss).start();
}
}
This code is just to explain the idea.

You can do something like:
while (true){
s=new ServerSocket(77);
ss=s.accept();
Thread at = new Thread(ss);
at.start();
}
Then the communication to the client happens in the run-method of 'at'.

Related

Java cannot read and write to socket at the same time

I am trying to build a simple multi client chat application using java sockets. The way I have gone about doing this is by having a client class that connects to a server class that waits for clients to connect and creates a new thread to deal with that client(Where the socket connection is read and written to). The client also reads from and writes to the socket connection to this thread. However, when the client wrote to the output stream of the socket, the server would not respond. A similar question here was posted:
Can you write to a sockets input and output stream at the same time?
One of the answers here says that you can read and write to a socket at the same time as long as reading from the socket is done on a separate thread.
Here is my client application:
public class Client {
Socket socket;
public static void main(String[] args) {
new Client();
}
public Client() {
try {
socket = new Socket("localhost", 4444);
new Thread() {
#Override
public void run() { //read from the input stream
try(
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
) {
String line;
while( (line = in.readLine()) != null ) {
System.out.println("Server said: " + line);
}
} catch(IOException e) {
}
}
}.start();
//write to output stream
try(
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
Scanner userInput = new Scanner(System.in);
){
System.out.println("Enter Something: ");
if(userInput.hasNextLine()) {
out.println(userInput.nextLine());
}
} catch (IOException e) {
}
} catch(IOException e) {
}
}
}
And my server application:
public class Server {
ServerSocket ss;
public static void main(String[] args) {
new Server();
}
public Server() {
System.out.println("Server Running...");
try {
ss = new ServerSocket(4444);
while(true) {
Socket socket = ss.accept();
new Thread() { //create new thread connection to client
#Override
public void run() {
new Thread() { //thread that reads inputstream
#Override
public void run() {
try(
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
) {
String line;
while( (line = in.readLine()) != null ) {
System.out.println("Client said: " + line);
//The problem seems to lie here.
}
} catch(IOException e) {
}
}
}.start();
//write to outputstream
try (
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
) {
String sendToClient = "Hey, my name is Server007 B)";
out.println(sendToClient);
} catch(IOException e) {
}
}
}.start();
}
} catch (IOException e) {}
}
}
I will run the server, then run the client, on the client side the output is
Server said: Hey, my name is Server007
Enter something:
Hello! <- enter anything
but the server does not print 'Client said: Hello!' like I expected it to. I hope I made my problem clear enough, thanks.
Ok, so I figured it out, I will answer my own question in case anyone makes the same mistake. The PrintWriter constructor should be this:
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
Not this:
PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
Alternatively, I could have done this:
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
I must have just gotten confused between BufferedWriter and PrintWriter :P

Muti - threaded Web Server in Java

I'm trying to build a server with Java.
My question is: how to do if I have multiple users at the same time? The answer is: multi threading. But I don't know how to do.
For example, if there is two client connected at the same time, and a server (who does 2*number) : if the client1 say "50" to the server and the client 2 "10", the server is supposed to return "100" to the first client and "20" to the second. But i'm not sure my code works.
Server side:
public class Server {
public static void main(String[] args){
ServerSocket socket;
try {
socket = new ServerSocket(4444);
Thread t = new Thread(new Accept(socket));
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
class Accept implements Runnable {
private ServerSocket socketserver;
private Socket socket;
private int nbrclient = 1;
public Accept(ServerSocket s){
socketserver = s;
}
public void run() {
try {
socket = socketserver.accept();
in = new BufferedReader (new InputStreamReader (socket.getInputStream()));
String message = in.readLine();
System.out.println(message);
out = new PrintWriter(socket.getOutputStream());
out.println("Pong");
out.flush();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client side:
public class Client {
public static void main(String[] zero) {
Socket socket;
BufferedReader in;
PrintWriter out;
try {
socket = new Socket(InetAddress.getLocalHost(),4444);
out = new PrintWriter(socket.getOutputStream());
out.println("Ping");
out.flush();
in = new BufferedReader (new InputStreamReader (socket.getInputStream()));
String message = in.readLine();
System.out.println(message);
socket.close();
}catch (UnknownHostException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}
If you have any ideas (how to do multi-threading and how to verify if my code works, like run two Clients.java and check if the multi-threading works)
The Server sides needs a while loop:
public class Server {
public static void main(String[] args){
ServerSocket socket;
try {
while(true){
socket = new ServerSocket(4444);
Socket socketInstance = socket.accept();
Thread t = new Thread(new Accept(socketInstance));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class Accept implements Runnable {
private Socket socket;
private int nbrclient = 1;
public Accept(Socket s){
socket = s;
}
public void run() {
try {
in = new BufferedReader (new InputStreamReader (socket.getInputStream()));
String message = in.readLine();
System.out.println(message);//this message should be your number
Double number = Double.parseString(message);
out = new PrintWriter(socket.getOutputStream());
//out.println("Pong");
out.println(2*number +"");
out.flush();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The client side looks ok. Just replace out.println("Ping"); with out.println("50"); or whatever you want.
You first start the server and then you can start multiple client applications. If you have any errors you can then post them here and have a look on an exact scenario.

Java TCP Client listening and writing to TCP Server

I have one TCP-Client and one TCP-Server written in Java. The Server is waiting for instructions from the Client but should also be able to send instructions to the client.
I can make the Client send something to the Server and wait for a reply. But I can not make it like waiting for a message without sending something before.
TCP-Client
public class TCPClient {
static DataOutputStream toServer;
static BufferedReader fromServer;
static Socket socket;
public static void main(String[] args) throws Exception {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
System.out.println("*************************");
System.out.println("* Client *");
System.out.println("*************************");
System.out.println("INSTRUCTION | EFFECT");
System.out.println("aktiv | ready to do something");
System.out.println("exit | disconnect");
System.out.println();
System.out.print("Please enter the IP-Address of the Server: ");
String ip = input.readLine();
System.out.println();
try {
socket = new Socket(ip, 9999);
} catch (Exception e) {
System.out.println("Can not connect to Server!");
}
toServer = new DataOutputStream(socket.getOutputStream()); // Datastream FROM Server
fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (sendRequest()) {
receiveResponse();
}
socket.close();
toServer.close();
fromServer.close();
}
private static boolean sendRequest() throws IOException {
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line;
boolean holdTheLine = true; // Connection exists
System.out.print("> ");
line = input.readLine();
switch (line) {
case "aktiv":
toServer.writeBytes("active" + '\n');
break;
case "exit":
holdTheLine = false;
break;
default:
break;
}
return holdTheLine;
}
private static void receiveResponse() throws IOException {
System.out.println("Server: " + fromServer.readLine() + '\n');
}
}
TCP-Server
public class TCPServer {
static boolean connected = true;
public static void main(String[] args) throws Exception {
System.out.println("********************************");
System.out.println("* Server *");
System.out.println("********************************");
System.out.println("INSTRUCTION | EFFECT");
System.out.println("ok | send an ok to client");
ServerSocket listenSocket = new ServerSocket(9999);
while (true) {
final Socket client = listenSocket.accept();
Thread newClientThread = new Thread(new Runnable() {
#Override
public void run() {
multithreadedServer(client);
}
});
newClientThread.start();
}
}
public static void multithreadedServer(Socket client) {
String line;
final BufferedReader fromClient;
final DataOutputStream toClient;
Thread cmdForClient;
try {
fromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
toClient = new DataOutputStream(client.getOutputStream());
while (connected) {
cmdForClient = new Thread(new Runnable() {
#Override
public void run() {
try {
String line = fromClient.readLine();
System.out.println("Client: " + line);
if (line.equals("exit")) {
connected = false;
}
} catch (Exception e) {
System.out.println(e);
}
}
});
cmdForClient.start();
final BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
try {
String reply = input.readLine();
if (reply.equals("ok")) {
toClient.writeBytes("OK." + '\n');
}
} catch (Exception e) {
System.out.println(e);
}
}
fromClient.close();
toClient.close();
client.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
The typical operation for a client-server scenario is for the client sending requests to the server. However, in peer to peer applications, both endpoints might act as both clients and servers. The only difference would be which endpoint that opened the connection. In your case, the problem is that only the "server" is using a receiver thread. Start a receiver thread at the client side and your problem should be solved. You should pretty much be able to just reuse your threaded code from the server in the client. Just pass the socket to the receive thread after opening the connection to the server.
EDIT:
In your client:
Thread newServerThread = new Thread(new Runnable() {
#Override
public void run() {
multithreadedServer(socket);
}
});
newServerThread.start();
where socket, is the socket to the server. You may need to update multithreadedServer for any specifics or differences for the clients operations, but the principle should be the same.

How to enable multiple clients to communicate with the server?

The problem am having is that am not sure how to enable multiple clients to communicate with the server through threading, i've attempted it but I think am doing something wrong. Any help will be appreciated.
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
ArrayList clientOutputStreams;
public class ClientHandler implements Runnable {
BufferedReader reader;
Socket sock;
public ClientHandler(Socket clientSocket) {
try {
sock = clientSocket;
InputStreamReader isReader = new InputStreamReader(
sock.getInputStream());
reader = new BufferedReader(isReader);
} catch (Exception x) {
}
}
public void run() {
String message;
try {
while ((message = reader.readLine()) != null) {
System.out.println("read" + message);
tellEveryone(message);
}
} catch (Exception x) {
}
}
}
public void go() {
clientOutputStreams = new ArrayList();
try {
ServerSocket serverSock = new ServerSocket(5000);
while (true) {
Socket clientSocket = serverSock.accept();
PrintWriter writer = new PrintWriter(
clientSocket.getOutputStream());
clientOutputStreams.add(writer);
Thread t = new Thread(new ClientHandler(clientSocket));
t.start();
System.out.println("got a connection");
}
} catch (Exception x) {
}
}
public void tellEveryone(String message) {
Iterator it = clientOutputStreams.iterator();
while (it.hasNext()) {
try {
PrintWriter writer = (PrintWriter) it.next();
writer.println(message);
writer.flush();
} catch (Exception x) {
}
}
}
public static void main(String[] args) {
new ChatServer().go();
}`enter code here`
}
To allow multiple client to connect to your server you need a server to be continually looking for a new client to connect to. This can be done like:
while(true) {
Socket socket = Ssocket.accept();
[YourSocketClass] connection = new [YourSocketClass](socket);
Thread thread = new Thread(connection);
thread.start();
}
This is probably also best done in a separate server java file that can run independent of the client.

BufferedWriter.write() does not seem to work

I have two Java applications, where an Android client connects to a server on a computer and sends a message using BufferedWriter over websockets.
The client:
try {
toast("Sending...");
Socket sock = new Socket(ip, PORT);
OutputStream os = sock.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
bw.flush();
bw.write("Hello Server!");
toast("Connected!");
} catch (UnknownHostException e) {
toast(e.getMessage());
} catch (IOException e) {
toast(e.getMessage());
}
The server:
public static void main(String[] args) {
ServerSocket server;
ConnectionThread ct;
Socket s;
ExecutorService es = Executors.newSingleThreadExecutor();
try {
System.out.println("Starting server...");
server = new ServerSocket(1337);
s = server.accept();
ct = new ConnectionThread(s);
es.execute(ct);
} catch (IOException ex) {
ex.printStackTrace();
}
}
The ConnectionThread class:
public class ConnectionThread implements Runnable {
private Socket sock;
private InputStream is;
private BufferedReader br;
private boolean online;
public ConnectionThread(Socket s) {
System.out.println("Creating connection thread.");
this.sock = s;
online = true;
}
#Override
public void run() {
String input = "";
try {
System.out.println("Starting to read...");
is = sock.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
while (online) {
input = br.readLine();
if(input != null){
System.out.print("Received message: ");
System.out.println(input);
}
}
br.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
When I run the server, and then the client, the client will show the "Connected!" toast, and the server's output will be:
Starting server...
Creating connection thread.
Starting to read...
So, it seems like the connection is actually being made, but the message does not arrive. Does anybody know why this could be happening?
Your server is expecting a complete line terminated by a newline. Try:
bw.write("Hello Server!");
bw.newLine();
Do it like this...
String s = new String();
while ((br.readLine())!=null) {
s = s+br.readLine();
System.out.print("Received message: ");
System.out.println(input);
}
}
And
bw.println("Hello Server");
I notice that you don't send an endline on your client, so the BufferedReader.readline() will never return, because it cannot match the \n-character. Try it again with
bw.write("Hello Server!\n");
on the client side.

Categories