I have a technogical question regarding Java Sockets.
For example lets assume I have one Java Sockets Server and n multiple clients.
Is it possible to send data from the Server to any or all Clients in nearly realtime?
More precisely:
Is there kind of Listener which can be implemented in a Sockets Client?
or do I need a loop in the client code where I ask every x milliseconds if there is a task for me?
Can somebody tell me what approach would be the best one?
And in addition if somebody has a code example I would be happy too.
Thanks!
You can establish a Thread in your client which listens to the socket and waits. It will continue when it gets data from the server.
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
public class ResponseThread extends Thread {
private final Socket socket;
/**
* Client is a selfmade interface which has no direct connection to socket communication.
* i build it to provide start(), stop() and isRunning() methods.
*/
private final Client client;
/**
* #param client encapsulated methods to check and manage the client status itself.
* #param socket the socket which is connected to the server.
*/
public ResponseThread(final Client client, final Socket socket) {
this.client = client;
this.socket = socket;
}
#Override
public void run() {
ObjectInputStream reader = null;
try(ObjectInputStream reader = new ObjectInputStream(socket.getInputStream())) {
while (client.isRunning()) {
try {
// The thread will wait here until the server sends data.
final String line = (String) reader.readObject();
if (null == line || line.isEmpty()) {
client.stop();
} else {
System.out.println(line);
}
} catch (IOException | ClassNotFoundException e) {
client.stop();
}
}
} catch (IOException ex) {
System.out.println("ERROR Abort reading. Could not establish InputStream from Socket.");
} finally {
try {
reader.close();
} catch (IOException ex) {
System.out.println("FATAL Could not close Socket.InputStream.");
}
}
}
public Socket getSocket() {
return socket;
}
}
Related
I'm programming in Java and i'm making a socket connection between server and several clients (using threads).
In the client side i made an opened Socket that connects to the server in a respective port and i send several objects, then the client disconnects.
In the server side i made a ServerSocket (where the client connects) and i use the accept() method to get the Socket, i don't want the socket to close so i keep it opened until i want (using a method for example), then i create an stream (ObjectInputStream) and read every object sent from the client, but i don't want it to close too. To continue the understanding of my problem here is the class i made:
import java.io.*;
import java.net.*;
public class ServerConnection implements Runnable{
private Socket connection;
public ServerConnection(Socket c){
connection = c;
}
#Override
public void run() {
// I used String i this example, but the real code use a Object sending system that i created
// because i needed to send different objects in one object (this ones implements Serializable).
String msg;
try {
ObjectInputStream inStream = new ObjectInputStream(connection.getInputStream());
do{
inStream.
msg = ((String)inStream.readObject());
System.out.println(msg);
}
while(!msg.equals("FINISH CONNECTION"));
} catch (IOException ex) {
System.err.println("run() - (io): "+ex.getMessage());
try {
connection.close();
} catch (IOException ex1) {
System.err.println("run() - (io/io): "+ex.getMessage());
}
} catch (ClassNotFoundException ex) {
System.err.println("run() - (classNF): "+ex.getMessage());
}
}
// The main method was created to make tests
// I'll use objects of this class to every client connection
public static void main(String[] args){
try {
ServerSocket server = new ServerSocket(8010);
Socket connection = server.accept();
ServerConnection svConnection = new ServerConnection(connection);
Thread theThread = new Thread(svConnection);
theThread .start();
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
}
This can receive the Strings i sent from the client, but the do-while isn't able to catch exceptions, the IOException is throwed when the Stream has no more Strings, so i want to prevent the throwing of that exception when the stream doesn't have more Strings to read, i tried to use recursive try-catch but i know that is not recommended. So there is another solution to this?
(Every answer is welcome. Thanks)
(EDIT)
For those one who needs the client code, so here it is:
import java.io.*;
import java.net.*;
public class ClientConnnection{
// There is a method that i don't make yet
public static void main(String[] args){
try {
Socket socketToServer = new Socket("localhost",8010);
ObjectOutputStream outStream = new ObjectOutputStream(socketToServer.getOutputStream());
outStream.writeObject(new Message("Hello :D"));
outStream.writeObject(new Message("How r u?"));
outStream.writeObject(new Message("Other message"));
outStream.flush();
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
I'm using a server socket to accept clients on the main thread, when a thread is accepted,the clients socket is given to a handler which is started in a new thread to process communications. However, before I start running my server to access clients, it connects to a second server which it must list to and be able to respond to and pass on the messages it gets to it's clients.
Hopefully this image illustrate what I mean:
The small server must be continuously listening for input from the big server, and also able to output responses.
//Default constructor
private smallServer(){}
//method to initialise and start the server
public static void StartServer(int port) throws IOException {
smallServer ss = new smallServer();
ss.bs= new bigServerClient(ss);
Thread nsc_Thread = new Thread(ss.bsc);
bsc_Thread.start();
//accepts clients and starts new thread for them
ss.ServerRun(port);
}
private void ServerRun(int port) throws IOException {
ServerSocket server = new ServerSocket(port);
server.setSoTimeout(50);
while (run) {
Socket client = null;
try {
client = server.accept();
} catch (SocketTimeoutException e) {
}
if (client != null) {
ClientHandler handler = new ClientHandler(client, this);
Thread handleThread = new Thread(handler);
handleThread.start();
}
}
if (!run) {
synchronized (ClientHandler.handlers) {
for (ClientHandler handler : ClientHandler.handlers) {
handler.terminateHandler();
}
}
System.exit(0);
}
}
public void processBigServerCommand(String toProcess) {
System.out.println("RESEAVED: " + toProcess);
}
The big server client(on the small server) then does this:
public class bigServerClient implements Runnable {
private smalsServer ss;
private PrintWriter printer;
private BufferedReader reader;
private Socket socket;
public bigServerClient(smallServer _ss) throws IOException {
ss = _ss;
socket = new Socket("Localhost", 5000);
printer = new PrintWriter(socket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
printer.flush();
SendBigServerMessage("Starting String");
}
private void SendBigServerMessage(String toSend) {
printer.print(toSend);
printer.flush();
}
#Override
public void run() {
try {
while (ss.state()) {
String inputLine;
while ((inputLine = reader.readLine()) != null) {
ss.processBigServerCommand(inputLine);
System.out.println(inputLine);
}
}
} catch (IOException e) {
} finally {
try {
socket.close();
} catch (IOException ex) {
}
}
}
}
From what's above, can anyone see why the big server client isn't responding to the big server when a message is sent? I'm guessing it's something to do with the main thread blocking the second thread, but I'm not sure... Any help would be greatly appreciated.
You lost me in your code...
Simplify it.
Your smallServer (see class names conventions) should have persistent connection to BigServer (effectively it is BigServer client) - you can implement it in your smallServer class, it should connect (once) and open I/O to BigServer (once) and close everything once the connection is terminated.
As your smallServer will handle multiple clients and pass their requests to BigServer there is no guarantee of the order of BigServer responses - you should do something to handle that (maybe pass UUID with requests?)
Simplify your smallServer and make sure that it runs...
i am creating a multiple-client/server app whenever any client disconnects from
my server it just hangs.
how can i set any condition that will tell me print some message whenever
any client disconnects from the server
here is my server code
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
System.out.println("server starting.......");
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Ready to accept.......");
socket = serverSocket.accept();
System.out.println(" client Connected with ip address =" +socket.getRemoteSocketAddress().toString());
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
System.out.println("catch block");
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
any help will be appreciated
It's not clear whether you mean disconnect because the conversation was over (ie: everything completed successfully) or the disconnect is because of some network problems (or the client canceled the request).
If it's the first case, then it's easy: the protocol you are using (your own, or http, or whatever) is in charge of defining how to determine that a conversation was over. If that situation arises, then you just close the socket.
If it's the second case, then you'd have to have an algorithm in place to determine whether or not the connection must be closed. For instance, by implementing a timeout, or a slow-read threshold. Take a look at the Socket's javadoc for instructions on how to set a timeout.
It's also worth noting that it's fine to create your own servers when you want to practice or learn something, but you'd be better off using an existing solution, like vert.x or a slimmed down version of Wildfly, for instance. The overhead of such servers is very low, nowadays, while still providing very robust networking capabilities.
Given the following code:
Client c1 = new Client();
c1.connect("127.0.0.1",1300);
Connect function:
public void connect(String serverName, int port)
{
try {
Socket socket = new Socket(serverName,port);
connection = new ConnectionProxy(socket);
connection.start();
}
catch(IOException e)
{
e.printStackTrace();
}
}
(ConnectionProxy class extends Thread) :
public class ConnectionProxy extends Thread {
private Socket socket;
private InputStream is;
private OutputStream os;
private StringConsumer client;
public ConnectionProxy(Socket socket)
{
this.socket = socket;
try {
is = socket.getInputStream();
os = socket.getOutputStream();
}
catch(IOException e)
{
e.printStackTrace();
}
}
public void run () {
DataInputStream dis = new DataInputStream(is);
DataOutputStream dos = new DataOutputStream(os);
while (socket != null)
{
try {
String msg = dis.readUTF();
System.out.println(msg);
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
I'm trying to implement a chat and I'm finding it difficult to send a message written by a client to all of the currently connected clients.
How could I do that? Should I hold the reference for each object (like c1) on the server side, or should I hold that ConnectionProxy thread on the server side?
If not, how do I implement that correctly and efficiently?
Would love to get some help!
Thanks!
Without being given much code, I'll outline what you'd want to do to achieve your goal.
On your server:
Keep an array or something similar of all connected client objects
Implement a send() function in your client class
Implement a broadcast() function that loops through the client list and sends each of them the message (using the aforementioned send() function
Make sure to keep track of (and remove) any dead/disconnected clients from your list, otherwise you'll run into trouble trying to send to them.
On your client:
Make sure you send a "connection terminated" message when you close/disconnect to tell the server you're leaving (makes it easier for the server to remove you)
The server should create a new client handler thread for each incoming connection.
For example, on the server side try something like:
ServerSocket server = new ServerSocket(port);
while (true) {
Socket client = server.accept();
//add incoming client to connected clients vector.
HandleClient c = new HandleClient(client);
clients.add(c);
}
After creating and storing clients in your vector of clients, you can the implement on the HandleClient class run() method a bufferReader (again not a must) to get your client text
I have a chat program. Now the code works for communicate between client and server via command line. But it gives an exception (java.net.SocketException: Socket is closed) while running. Please help me to fix that problem.
In a java chat program,how will the communication be implemented between client and server?
ie.
client<-->server (between server and client)
or
client A<-->server<-->client B (server act as a bridge between two clients)
Is the 2 way communication can be implemented through a single socket?
Are there any other methods ?
How to communicate more than one client simultaneously?
server code
class Server
{
ServerSocket server;
Socket client;
public Server()
{
try
{
server = new ServerSocket(2000);
System.out.println("\tServer Started..........");
while (true)
{
client = server.accept();
Send objsend = new Send(client);
Recive objrecive = new Recive(client);
//client.close();
}
}
catch (Exception e)
{
System.out.println("Exception4 " + e);
}
}
public static void main(String arg[])
{
new Server();
}
}
class Recive implements Runnable
{
Socket client;
public Recive(Socket client1)
{
client=client1;
Thread trsend=new Thread(this);
trsend.start();
}
public void run()
{
ObjectInputStream ois;
Message M=new Message();
try
{
ois = new ObjectInputStream(client.getInputStream());
M = (Message)ois.readObject();
M.display();
ois.close();
}
catch (Exception e)
{
System.out.println("Exception1 " + e);
}
}
}
class Send implements Runnable
{
Socket client;
public Send(Socket client1)
{
client=client1;
Thread trrecive=new Thread(this);
trrecive.start();
}
public void run()
{
Message M=new Message();
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
try
{
System.out.println("Me(server)");
M.strmessage=br.readLine();
ObjectOutputStream oos=new ObjectOutputStream(cli ent.getOutputStream());
oos.writeObject((Message)M);
oos.flush();
oos.close();
}
catch (Exception e)
{
System.out.println("Exception " + e);
}
}
}
client code
class Client
{
public static void main(String arg[])
{
try
{
Send objsend=new Send();
Recive objrecive=new Recive();
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
class Send implements Runnable
{
public Send()
{
Thread trsend=new Thread(this);
trsend.start();
}
public void run()
{
try
{
Message M=new Message();
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
while(true)
{
System.out.println("Me(client)");
M.strmessage=br.readLine();
Socket client=new Socket("localhost",2000);
ObjectOutputStream oos=new ObjectOutputStream(client.getOutputStream());
oos.writeObject((Message)M);
oos.flush();
oos.close();
}
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
class Recive implements Runnable
{
public Recive()
{
Thread trrecive=new Thread(this);
trrecive.start();
}
public void run()
{
try
{
while(true)
{
Socket client=new Socket("localhost",2000);
ObjectInputStream ois=new ObjectInputStream(client.getInputStream());
Message CNE=(Message)ois.readObject();
CNE.display();
ois.close();
}
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
First of all, don't close the streams in every run().
Secondly, check whether port for server which you are using is free.
This program makes your pc both host and server.
import java.io.IOException;
import java.net.*;
public class ClientServer {
static byte[] buffer = new byte[100];
private static void runClient() throws IOException {
byte buffer[] = new byte[100];
InetAddress address = InetAddress.getLocalHost();
DatagramSocket ds=new DatagramSocket();
int pos = 0;
while (pos<buffer.length) {
int c = System.in.read();
buffer[pos++]=(byte)c;
if ((char)c =='\n')
break;
}
System.out.println("Sending " + pos + " bytes");
ds.send(new DatagramPacket(buffer, pos, address, 3000));
}
private static void runServer() throws IOException {
InetAddress address = InetAddress.getLocalHost();
DatagramSocket ds = new DatagramSocket(3000, address);
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
ds.receive(dp);
String s=new String(dp.getData(),0,dp.getLength());
System.out.print(s);
}
public static void main(String args[]) throws IOException {
if (args.length == 1) {
runClient();
} else {
runServer();
}
}
}
also follow this link
There could be multiple places where the exception could be thrown. Without a stack trace it is difficult to state so accurately, as to the cause of failure.
But the root cause, is essentially due to the fact that you are closing the InputStream of the socket in your Receiver threads after reading a message, and closing the OutputStream of the socket in your Sender threads after sending a message. Closing either of these streams will automatically close the socket, so you if attempt to perform any further operation on it, a SocketException will be thrown.
If you need to ensure that your server and client do not shutdown in such an abrupt manner, you'll have to keep reading the InputStream (until you get a special message to shutdown, for instance). At the same time, you'll also have to keep writing to the OutputStream. Two-way communication is definitely possible, and the posted code is capable of the same (if the socket remains open).
If you have to handle multiple clients, you'll need multiple reader and writer threads on the server, each listening on an instance of a Socket returned from ServerSocket.accept(); in simpler words, you need a reader-writer pair listening on a distinct socket on the server for each client. At the moment, multiple clients can connect to the Server, as each incoming connection is provided its own client Socket object on the Server, that is provided to individual reader and writer threads. The main Server thread can continue to receive incoming connections and delegate the actual work to the reader-writer pairs.
chat programms normaly have a server through which all communication goes. The reason is that other wise every client needs to know how to reach every other client. And that doesn't work in the general case.
So you'll have a server, every client registers and talks with the server, which will forward messages to other clients.
Mostly communication is done via HTTP cause this is likely to go through firewalls and proxies. You probably want to read up on long polling if you are planning for anything serious.