i have a client_1 , centerlized_server and server_1
the client send request to a centerlized_server
and centerlized_server transfer the request to the server_1
the problem is how i transfer the request from centerlized_serve to server_1??
I appreciate your help
...
Client1 code
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Client1 {
private Socket server;
private ObjectOutputStream out;
private ObjectInputStream in;
public Client1() {
try
{
server = new Socket("localhost", 5050);
out = new ObjectOutputStream(server.getOutputStream());
in = new ObjectInputStream(server.getInputStream());
while (true)
{
Scanner s = new Scanner(System.in);
System.out.println("press 2 to date or 1 for time:");
Message msg = new Message();
msg.Type = s.nextInt();
out.writeObject(msg);
msg = (Message) in.readObject();
System.out.println(msg.message);
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args) {
new Client1();
}
}
CernterlizedServer code
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Date;
public class CentralizedServer extends Thread {
private Socket client;
private ObjectOutputStream out;
private ObjectInputStream in;
public CentralizedServer(Socket current_socket)
{
try
{
client = current_socket;
out = new ObjectOutputStream(client.getOutputStream());
in = new ObjectInputStream(client.getInputStream());
}
catch (Exception ex) {
ex.printStackTrace();
}
}
#Override
public void run()
{
try
{
while (true)
{
Message msg = (Message) in.readObject();
if (msg.Type == 1)
{
OnTimeRequst();
}
else if (msg.Type == 2)
{
OnDateRequst();
}
}
}
catch (Exception ex)
{
try
{
out.close();
in.close();
client.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
private void OnTimeRequst() throws IOException
{
Date d = new Date();
Message msg = new Message();
msg.message = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
out.writeObject(msg);
}
private void OnDateRequst() throws IOException
{
Date d = new Date();
Message msg = new Message();
msg.message = d.toString() + "";
out.writeObject(msg);
}
}
Server code
import java.net.ServerSocket;
import java.util.ArrayList;
public class Server {
ServerSocket server;
ArrayList<CentralizedServer> list = new ArrayList<>();
public Server()
{
try
{
server = new ServerSocket(5050);
while (true)
{
CentralizedServerthr = new CentralizedServer(server.accept());
list.add(thr);
thr.start();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public static void main(String... args) {
new Server();
}
}
You can design this one of two ways.
Option 1: Redirect. The centralized server sends back a response to the client to "redirect" him to server1. (ala http 30x response). Then the client just makes a separate connection to server1 and resends the request.
Option 2: Proxy. Upon receiving the request from the client, the centralized server makes a connection to server1 and sends the request on behalf of the client. When the centralized server receives the response from server1, it just forwards the response to the client.
The redirect method is simpler, but not always possible if "server1" is meant to be protected from direct client access or only accessible from other servers.
The proxy method is a bit harder, but allows for different designs.
Related
I'm working with "ServerSocket" and "Socket", the problem I'm going through is this: I create a server using serverSocket, I'm waiting for the client to connect, when it connects I'll receive some information, and here's my question, how do I keep listening to the client and receive instructions from it?
In the example below I am creating a server, when the client connects I save the connection within the "clientSocket ".
#GET
#Path("/createServer")
public String conect() throws IOException {
serverSocket = new ServerSocket(3242);
clientSocket = serverSocket.accept();
...
...
}
From this point I need to always listen to this clientSocket, when the client send some information I need to capture to perform some actions, how to do that?
ServerSocket.accept() gives you a java.net.Socket. Doc here
From there on, you can read on that socket using its input stream (Socket.getInputStream()) or write to its output stream (Socket.getOutputStream())
Your sockets (client and server) will live until they're closed, or garbage collected, so remember to keep a strong reference to each one as long as you need them.
Sample programs (simple echo server. Type bye in client to exit):
Server.java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Server {
private static volatile boolean stopped = false;
public static void main(String[] args) throws IOException, InterruptedException {
try (ServerSocket server = new ServerSocket(3001)) {
System.out.println("Server ready to accept connections on port " + server.getLocalPort());
final Socket client = server.accept();
System.out.println("Client connected using remote port " + client.getPort());
final Thread t = new Thread(() -> {
try {
try (InputStream clientIn = client.getInputStream()) {
try (OutputStream clientOut = client.getOutputStream()) {
echo(clientIn, clientOut);
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
stopped = true;
}
});
t.setDaemon(true);
t.start();
while (!stopped) {
Thread.sleep(10);
}
System.out.println("Program exit");
}
}
private static void echo(InputStream clientIn, OutputStream clientOut) throws IOException {
try (Scanner clientScan = new Scanner(clientIn, StandardCharsets.UTF_8)) {
try (OutputStreamWriter clientWriter = new OutputStreamWriter(clientOut, StandardCharsets.UTF_8)) {
while (!stopped) {
final String fromClient = clientScan.nextLine();
System.out.println("In: " + fromClient);
clientWriter.write(fromClient);
clientWriter.write(System.lineSeparator());
clientWriter.flush();
if ("bye".equalsIgnoreCase(fromClient.trim())) {
stopped = true;
}
}
System.out.println("Loop done");
}
}
}
}
Client.java
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Client {
private static volatile boolean stopped = false;
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("Client launched");
try (Socket client = new Socket("localhost", 3001)) {
System.out.println("Connected on remote port " + client.getPort() + " from " + client.getLocalPort());
try (Scanner console = new Scanner(System.in)) {
try (OutputStreamWriter toServer = new OutputStreamWriter(client.getOutputStream())) {
final Thread t = new Thread(() -> printEverything(client));
t.setDaemon(true);
t.start();
while (!stopped) {
final String fromConsole = console.nextLine();
if (stopped)
break;
toServer.write(fromConsole);
toServer.write(System.lineSeparator());
toServer.flush();
}
}
}
}
System.out.println("Program exit");
}
private static void printEverything(Socket client) {
try (Scanner server = new Scanner(client.getInputStream())) {
while (!stopped) {
final String fromServer = server.nextLine();
System.out.println("Server said: " + fromServer);
if ("bye".equalsIgnoreCase(fromServer.trim())) {
stopped = true;
}
}
System.out.println("Loop done. Press enter to exit");
} catch (IOException e) {
e.printStackTrace();
stopped = true;
}
}
}
I've recently been playing around with Sockets in Java but I came across a problem. The server get's stuck in the Server readLine(); I have no clue what is going on, if anyone can help that would be great. I know that the problem is not that readLine() only returns when there is a new line character, but I am using println() not just print().
Here is my current code:
Server Class:
package packets.sidedcomputer;
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 packets.Packet;
import packets.data.PacketData;
import packets.info.ClientInfo;
import packets.reciever.PacketReciever;
import packets.sender.PacketSender;
import packets.side.Side;
public class Server extends SidedComputer
{
volatile boolean finished = false;
public ServerSocket serverSocket;
public volatile List<ClientInfo> clients = new ArrayList<ClientInfo>();
public void stopServer()
{
finished = true;
}
public Server()
{
try
{
serverSocket = new ServerSocket(10501);
}
catch (IOException e)
{
e.printStackTrace();
}
}
#Override
public void run()
{
try
{
while (!finished)
{
Socket clientSocket = serverSocket.accept();
if(clientSocket != null)
{
ClientInfo clientInfo = new ClientInfo(clientSocket);
this.clients.add(clientInfo);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String dataString = in.readLine();
while(dataString != null && !dataString.equals(""))
{
PacketReciever packetReciever = new PacketReciever();
PacketData packetData = new PacketData();
packetData.decodeInto(dataString);
Packet packet = packetReciever.recievePacket(packetData, packetData.packetID, getSide(), clientSocket.getLocalAddress().getHostAddress().toString(), clientSocket.getLocalPort() + "");
PacketSender packetSender = new PacketSender();
for (ClientInfo client : this.clients)
{
PrintWriter out = new PrintWriter(client.socket.getOutputStream(), true);
packetSender.sendPacketToClient(packet, out);
}
dataString = in.readLine();
}
serverSocket.close();
}
}
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
#Override
public Side getSide()
{
return Side.SERVER;
}
}
My Client Class:
package packets.sidedcomputer;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import packets.MessagePacket;
import packets.sender.PacketSender;
import packets.side.Side;
public class Client extends SidedComputer
{
volatile boolean finished = false;
volatile String username;
volatile Server server;
public Socket clientSocket;
public ClientReciever reciever;
public Client(Server server, String username) throws UnknownHostException, IOException
{
this.username = username;
this.server = server;
this.reciever = new ClientReciever(this);
}
public void stopClient()
{
finished = true;
}
#Override
public void run()
{
Scanner scanner = new Scanner(System.in);
reciever.start();
while(!finished)
{
try
{
this.clientSocket = new Socket("192.168.1.25", 10501);
String line;
while((line = scanner.nextLine()) != null)
{
PacketSender sender = new PacketSender();
sender.sendPacket(new MessagePacket(line, username), clientSocket.getLocalAddress().getHostAddress().toString(), "" + clientSocket.getPort());
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
scanner.close();
}
#Override
public Side getSide()
{
return Side.CLIENT;
}
}
My packet sender class:
package packets.sender;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import packets.Packet;
import packets.data.PacketData;
public class PacketSender implements IPacketSender
{
#Override
public void sendPacket(Packet packet, String host, String port)
{
if(packet.getDefualtID() == 0)
{
PacketData packetData = new PacketData(packet.getDefualtID());
packet.writeData(packetData);
String data = packetData.encodeIntoString();
sendData(host, port, data);
}
}
protected void sendData(String hostName, String port, String data)
{
try
{
try
(
Socket socket = new Socket(hostName, Integer.parseInt(port));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
)
{
out.println(data);
}
catch (UnknownHostException e)
{
System.err.println("Don't know about host " + hostName);
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to " + hostName);
System.exit(1);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void sendPacketToClient(Packet packet, PrintWriter out)
{
PacketData packetData = new PacketData(packet.getDefualtID());
packet.writeData(packetData);
String data = packetData.encodeIntoString();
out.println(data);
}
}
Here's what's happening
From your client:
this.clientSocket = new Socket("192.168.1.25", 10501);
When this line runs, the server will be woken up from the accept line. And block again at readLine()
Meanwhile, your client, goes through your PacketSender. What does your PacketSender do?
Socket socket = new Socket(hostName, Integer.parseInt(port));
This opens a new connection! So your Client is waiting for the server to accept a connection. And the server is waiting for the client to send a message! You arrive at a deadlock.
Here's how to fix it
remove the following line.
this.clientSocket = new Socket("192.168.1.25", 10501);
then pass the host address and port manually into your PacketSender.
I want that message sent by server should be delivered to all the clients however a message sent by by client should only be delivered to server.
Problem is when i run the code-
1.Server waits for client to connect
2.when multiple client connected
3.Now as the server broadcast the first message it is received by both the clients but when server broadcast the message second time. Both the clients has to send message in order to receive server message.
I am a noob in socket programming so please correct me what i am doing wrong?
So far i have made this program.
Server Code:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
import java.net.*;
import java.io.*;
public class Server_Side3
{
static Client_server t[] = new Client_server[10];
static LinkedList<Client_server> al = new LinkedList<Client_server>();
public static void main(String args[]) throws IOException
{
ServerSocket server = null ;
Socket socket = null;
try
{
int Port =9777;
server = new ServerSocket(Port);
System.out.println("Waiting for Client " + server);
while(true)
{
socket = server.accept();
System.out.println("Connected to " + socket.getLocalAddress().getHostAddress());
Client_server clients = new Client_server(socket);
al.add(clients);
clients.start();
}
}
catch (Exception e)
{
System.out.println("An error occured.");
e.printStackTrace();
}
try
{
server.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private static class Client_server extends Thread
{
Socket sockets;
PrintWriter out;
Client_server t[];
Client_server (Socket s )
{
sockets = s;
}
public void run()
{
try
{
InetAddress localaddr = InetAddress.getLocalHost();
Scanner sc = new Scanner(System.in);
Scanner in = new Scanner(sockets.getInputStream());
out = new PrintWriter(sockets.getOutputStream(),true);
String input = null;
while(true)
{
String servermsg = sc.nextLine();
broadcast(servermsg);
System.out.println("Message sent to client: "+servermsg);
input = in.nextLine();
System.out.println(localaddr.getHostName()+" Said :"+ input);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void broadcast(String servermsg)
{
Iterator it = al.iterator();
while(it.hasNext())
{
((Client_server) it.next()).send(servermsg);
}
}
private void send(String msg)
{
String servrmsg = msg;
out.println(msg);
out.flush();
}
}
}
Client Code :
import java.net.Socket;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientSide2
{
static Scanner chat = new Scanner(System.in);
public static void main(String[] args)
{
int Port = 9777;
String Host = "localhost";
try
{
Socket socket = new Socket(Host, Port);
System.out.println("You connected to "+ Host);
Scanner in = new Scanner(socket.getInputStream()); //GET THE CLIENTS INPUT STREAM
PrintWriter out = new PrintWriter(socket.getOutputStream());
String clientinput;
while(true)
{
System.out.println(in.nextLine());//If server has sent us something .Print it
clientinput=chat.nextLine();
out.println(clientinput); //SEND IT TO THE SERVER
out.flush();
}
}
catch (Exception e)
{
System.out.println("The server might not be up at this time.");
System.out.println("Please try again later.");
}
}
}
Im having a little problem i have managed to send info from client to server etc... but i want to be able to do it though telnet also (Open it up and say go telnet 127.0.0.1 4444, and then put in like 1 2 3 and then it comes up in the server just like it would if sending via the client. At the moment im getting this error:
java.io.StreamCorruptedException: invalid stream header: 310D0A32
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at ConnectionHandler.run(server1.java:73)
at java.lang.Thread.run(Unknown Source)
Let me know if i'm doing anything wrong please:
My main goal for this is to have it so i can enter say Username, ID and Name and then be able to recall them with a time, Like a very simple check in check out system. Would really love some help <3 :)
Client:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class client1 {
public static void main(String[] args) {
try {
// Create a connection to the server socket on the server application
Socket socket = new Socket("localhost", 7777);
// Send a message to the client application
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
//oos.writeObject("A B C");
String data[]=new String[3];
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter details for the array");
for(int x=0;x<3;x++){
System.out.print("Enter word number"+(x+1)+":");
data[x]=br.readLine();
}
oos.writeObject(data);
System.out.println("Details sent to server...");
oos.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.ClassNotFoundException;
import java.lang.Runnable;
import java.lang.Thread;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class server1
{
private ServerSocket server;
private int port = 4444;
public server1()
{
try
{
server = new ServerSocket(port);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
server1 example = new server1();
example.handleConnection();
}
public void handleConnection()
{
System.out.println("Waiting for client message got...");
// The server do a loop here to accept all connection initiated by the
// client application.
while (true)
{
try
{
Socket socket = server.accept();
new ConnectionHandler(socket);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
class ConnectionHandler implements Runnable
{
private Socket socket;
public ConnectionHandler(Socket socket)
{
this.socket = socket;
Thread t = new Thread(this);
t.start();
}
public void run()
{
try
{
// Read a message sent by client application
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message[] = (String[]) ois.readObject();
//System.out.println("Message Received from client: " + message);
//b(message);
printArray(message);
ois.close();
socket.close();
System.out.println("Waiting for client message is...");
}
catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
private void b(String message) {
List<String> list = new ArrayList<String>();
String[] arr = list.toArray(new String[0]);
System.out.println("Array is " + Arrays.toString(arr));
}
private void printArray(String[] arr){
for(String s:arr){
System.out.println(s);
}
}
hi i writ acode for client and for server and now i want to deliver the message between clint one to clint two and i dont succees to do this on server side i want to construct array for name and id and after i send message from the client side i can choose where or Which name the server deliver the message pleas help me to writ this
so this is the clint side
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class client {
public static void main(String[] args) {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 7777);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader readerFromCommandLine = new BufferedReader(new InputStreamReader(System.in));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
while(true) {
System.out.println("Say something:");
String userInput = readerFromCommandLine.readLine();
writer.println(userInput);
writer.flush();
String input = reader.readLine();
System.out.println("Got from server: "+input);
if (userInput.equalsIgnoreCase("bye")) {
break;
}
}
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
finally {
if (socket != null) {
try {
socket.close();
}
catch (Exception e) {
System.err.println(e);
e.printStackTrace();
}
}
}
}
}
so now my code shuold by look like this ?
becaus i not yet can send from one client to client two
import java.awt.List;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class server {
public static void main(String[] args) {
ArrayList<Channel> my_clients = new ArrayList<Channel>();
ServerSocket ss = null;
try {
ss = new ServerSocket(7777);
while (true) {
//wait for a new client call - once got it, get the socket for
//that channel
System.out.println("Waiting for an incoming call");
Socket client = ss.accept();
Channel my_new_client = new Channel(client);
my_clients.add(my_new_client);
my_new_client.start();
//once the call has started read the client data
for(Channel my_client : my_clients) {
if(my_client.getName() == "Me") {
//my_client.writer("HELLO!");
}
}
//System.out.println("Accepted a new call");
//new Channel(client).start();
}
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
finally {
if (ss != null) {
try {
ss.close();
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
}
}
}
public static class Channel extends Thread {
private static int clientIndex = 0;
private int index;
private Socket socket = null;
public Channel(Socket socket) {
clientIndex++;
index = clientIndex;
this.socket = socket;
}
#Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
while (true) {
String input = reader.readLine();
System.out.println("Got from client "+index+": "+input);
//bye bye
if (input.equalsIgnoreCase("bye")) {
break;
}
writer.println("Gotcha");
writer.flush();
}
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
finally {
if (socket != null) {
try {
socket.close();
}
catch(Exception e) {
System.err.println(e);
e.printStackTrace();
}
}
}
}
}
}
String userInput = readerFromCommandLine.readLine();
BufferedReader.readLine() is a problem here. It is going to block your thread until input is received. This means communication can only ever go in one direction at a time, and can potentially get totally blocked if both clients are waiting.
DataFetcher can fix this problem; you can use it to listen in a separate Thread
http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/
You half way there.
You created a Threaded Server were each connection from a client opens a thread. This thread then loops and waits for messages.
Think of these threads as you connected clients with their own objects / properties and their streams to write to and read from them.
So each time a clients connections you want to create their thread add it to some kind of list and start their thread. For example:
At the top of the class
List<Channel> my_clients = new List<Channel>();
In your while loop
Channel my_new_client = new Channel(client);
my_clients.add(my_new_client);
my_new_client.start();
Then when you want to send a message to a certain clients. You can loop all the Threads and look for one that has some kind of name or Unique Indentifier. For example:
for(Channel my_client : my_clients) {
if(my_client.getName() == "Me") {
my_client.write("HELLO!");
}
}
or in the same breath you could send a message to all your clients (Broadcast):
for(Channel my_client : my_clients) {
my_client.write("HELLO!");
}
remember to remove the clients when they disconnect too!
// Can't remember the precise exception correct my if I'm wrong!
catch(SocketException ex) {
my_clients.remove(this);
}
Note this expects that you some how authenticate and know the name of your client or supply them a UID which you reference when you are instructed to sent them something. And that the Channel class has the Write Method for connivance.
Hope that Help!