I have a server and many clients. My clients send messages through server. If a client connects to server, my server puts socket reference of this client to a Sock array. If another client sends message to this first client server checks whether first client is connected to server or not using a boolean array, if it is online then sends message to first client using the socket reference in array otherwise sends messages to database.
Every client sends close signal before logout to server so that it can update the boolean array.But if internet connection of first client goes off suddenly ,then boolean variable in the array will still be true. For this purpose i want to make a thread in server which checks boolean array,if any index in array is true ,i want to check whether socket corresponding to it is open or not. What method of socket should i use- socket.isConnected() or socket.isClosed() or any other?
The only way to be sure a connection is working is by receiving a heartbeat, or message at a regular interval.
There is isConnectd() which means; have I ever connected and isClosed() which means; did I call close() on my side, but these don't do what you might want.
Related
Kindly find in the details of assignment:
Start a TCP Server.
Start multiple clients to connect to the server.
On connect :
Server gives each connection a random unique name
Server starts sending PING messages to client as : “PING client abc123 at time hhmmss” every 5 seconds.
Client receives the PING messages and prints them to console.
On connect :
Client starts sending “Time request” messages every 10 seconds
Server gets the message and responds : “Client abc123, the time is hhmmss”
Client gets the time messages and prints them to console.
Things to note :
Use plain sockets (not NIO)
Make sure that the socket handling code is reusable
Make sure that the time request reads and writes are asynchronous.
Ensure that ping and all other reads and writes are also asynchronous
Ensure that ping and time response messages do not intersperse or corrupt each other
We are not here to write a program for you, but here is some stuff you can use to solve most of the problems in your project.
First off you are using TCP in Java so you will be using the following objects:
Socket - Client connection
ServerSocket - Server host
There is documentation on how to use these here.
Server side, you want multiple connections and you will want the rest of the program to run. This means multitasking. The ServerSocket should run on a separate thread. Then it should be put in a do-while loop to accept() connections. The server will then wait there until a client socket connects. When a connection is made you will need to create a new thread to let the ServerSocket accept more clients. Make sure when multi threading to use synchronized methods.
Create ServerSocket like this: new ServerSocket(port); This will open server on int port.
On the client side we will also use multithreading. The Socket will need to be on a seprate thread and to create a Socket to connect to an ip and port do the following: new Socket(ip, port) (ip is a String)
Once connected both the server and client will need to communicate. An easy way to do this is to send a message back and forth. You can't just not send because the server or client will pause and wait on receive and not be able to send. I will get to this issue in a minute.
One way to send would be to use a PrintWriter. Create a new PrintWriter with the Socket output stream. From here you can send by printing line with PrintWriter.
Make sure you flush or autoFlush your PrintWriter or else it will keep sending the same message over and over.
You can then receive a message by using BufferedReader by creating a new InputStreamReader from the socket input stream. Doing this you can use readLine(). Remember this will pause until something is received.
Doing this on both the server and client you can send back and forth. Once at this point you could easily do the rest of your requested assignment.
As I mentioned earlier, this method will result in the server and clients sending and receiving over and over even if the message is empty. Doing the following can prevent this and use less cpu and bandwidth as it will only send when it has a message to send:
(I created this diagram for a forum post for a project update I have created once)
The green lines represent received data going somewhere and the red represent data from the program going to the sender thread to be sent.
Notice on this diagram that there is a thread for receiving and sending. This allows one to send messages while the other receives, so the sender won't pause if the receiver does pause to wait to receive a message.
Other good resources:
Simple Chat Program
enter link description here
I am one server and multiple clients via threads. The client(s) send their message to the server. I have worked out how to make the server send the message back to client like a echo system. If I have two clients, I want them to send their message to the server and the server should send it to the client that did not send the message i.e. the other client. How would I go about send the message back to all the clients apart from the one that send the message?
When the message comes in, determine what the userID / other identifying id the incoming message is associated with. Then re-broadcast to all other sockets, but exclude the Socket associated with the ID that sent the message
Make at the server side a list with all the clients...
every time a new msg is received, then iterate the list and send the msg using the port of the socket as id...
I recently wrote a Chat program too. What I did was, I had a class ClientHandler that handles the connection for each individual client.
Inside ClientHandler I had a HashMap. I added each client that had connected to the HashMap, with the Key being the client id. I used a UUID rather than int for the client id.
Inside this handler class, I had a sendMessage(String str) method. Within this method, a for-each loop that loops through each ClientHandler object, checking the values inside the HashMap. Inside this for-each loop, I have an if statement that checks whether you are writing to the ClientHandler object with this id. If the check returns false, you go ahead and write the message on the PrintWriter and the message won't be sent to the client writing the message.
This worked for me. Might not work for you.
situation:-
client1: user side application where they connect to server with username. The connection is to stay alive with client1 waiting for messages from server.
client2: event fired application that asks server for all the users connected and closes its connection. It will process the users list and select one user. It will connect back to the server and ask it to send a message to the selected user.
Server: listen for client1 on 11111 and client2 on 22222. Connection with client1 is to be kept alive until user logs out in client1 software. client2 demands list, selects an element, asks server to relay message to that instance of client1. If client1 is down by that time, server responds with false and client2 goes back to step of getting list of live instances of client1.
Problem I am facing:-
How to implement a system in client1 so that it connects to server when user actions connect UI element, and then it keeps the connection live at all times, in case the connection goes down, it reconnects on its own. Simultaneously it should poll the inputstream to receive any messages that server might send while it is connected.
Precisely, I am facing a problem accessing the same single socket instance by 2 threads, one to keep connection alive and reconnect if went down, and another to keep looking for data in inputstream. If the KeepAlive thread checks connection and at the same time MessageReader thread would be receive data, then the system would crash.
What I usually do is use a read timeout on the client to initiate a server poll, then go back to reading. If another read timeout occurs, the client knows that its server is unreachable, closes its socket and falls back to attempting to re-open the connection every, say, 10 seconds. Pseudo-C:
boolean pollOustanding;
while true{
if connectAttempt(){
pollOutstanding:=false;
while(true){
if readWithTimeout(2000){
handleReceivedData(); // could be 'real' data, or poll reply from server
pollOutstanding:=false;
}
else
{ if (pollOutstanding) break;
pollOutstanding=true;
sendPoll();
};
};
closeSocket;
};
Sleep(10000);
};
Only needs one thread - you don't need to poll the sever if data is being received - the connection must be OK.
I have two clients A, B
also I have a server S
A sends a request to the server S, due to this request the server S wants to inform client B that client A made a request.
the same can happen if B sends a request to server S but this time server S will inform A
is this possible with the client server model? I have managed to create a simple program where client A sends a request to server S and displays the server's response. In this program server S listens to endless connections which means that I have something like this:
while(true){
Socket userSocket = serverSocket.accept();
new Connection(clientSocket);
//where in the Connection class we manage the connection events
}
but I can't understand how I can make the server 'S' a client inside the class "Connection" to the client that didn't send the request. If I do the same process I usually do for any client (A or B) I get an exception which prints some IP address and I'm not sure which ones because I run everything locally.
thanks in advance
Practically speaking you can do what you said, which is to have S notify B that A has made a request or vice versa. Conceptually though this doesn't mean that S is now a client of B. S is still a server it just happens to be sending B a message on its own rather than reacting to input from B.
Think about S representing a chat server. If A sends a message to S and S forwards it to B, is S now a client of B or still a server?
I have a socket running, using selectors. I am trying to check to see if my socket is connected to the server or not.
Boolean connected = _channel.isConnected();
and it always returns true. I turned off Airport (internet connection) on my computer, and when i check to see if the socket is connected or not, it still returns true.
Any idea why?
I try to write data to the server every 3 seconds, and it still doesn't change the state of my socket to disconnected.
Usually if you turn off OS level networking, writes to socket should throw exceptions, so you know the connection is broken.
However more generally, we cann't be sure if a packet is delivered. In java (probably C too), there is no way to check if a packet is ACK'ed.
Even if we can check TCP ACKs, it doesn't guarantee that the server received or processed the packet. It only means that the target machine received the packet and buffered it in memory. Many things can go wrong after that.
So if you really want to sure, you can't rely on transport protocol. You must have application level ACK, that is, the server application writes back an ACK message after it received and processed a message from client.
From client point of view, it writes a message to server, then tries to read ACK from server. If it gets it, it can be certain that its message is received and processed. If it fails to get ACK, well, it has no idea what has happened. Empirically, most likely TCP failed. Next possiblity is that server crashed. It's also possible that everything went OK, except the ACK couldn't reach the client.
A socket channel can be connected by invoking its connect method; once connected, a socket channel remains connected until it is closed.
The channel is not closed when the server is not available anymore, due to a broken physical connection or a server failure. So once a connection has been established, isConnected() will be returning true until you close the channel on your side.
If you want to check, if the server is still available, send a byte to the sockets outputstream. If you get an Exception, then the server is unavailable (connection lost).
Edit
for EJP - some code to test and reconsider your comment and answer:
public class ChannelTest {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket google = new Socket(InetAddress.getByName("www.google.com"), 80);
SocketChannel channel = SocketChannel.open(google.getRemoteSocketAddress());
System.out.println(channel.isConnected());
channel.close();
System.out.println(channel.isConnected());
}
}
Output on my machine is
true
false
isConnected() tells you whether you have connected the channel object, which you have, and it's not specified to return false after you close it, although apparently it does: see Andreas's answer. It's not there to tell you whether the underlying connection is still there. You can only tell that by using it: -1 from a read, or an exception, tells you that.