UDP socket and multiple replies - java

I'm a learner, so please be patient and clear. I am writing an echo client with Java sockets (DatagramSocket).
After the client sends a message to the echo server, the server deliberately sends 1-10 copies of the message back to simulate message duplication in UDP.
However, my code can only receive the first of those messages sent back, never the full number sent by the server. My receive code is like this:
socket.receive(receivePacket);
How would I put my client in a state where you can enter a string to echo, say "Hi", it is then sent to the server, but can then receive all the replies? I am assuming that they all make it back to the client (I am testing this on my local machine so there will be no loss)

Call socket.receive again to receive additional packets. Set a timeout to wait a reasonable amount of time before deciding the server has sent all its packets.

Related

ChatServer in java

I did a simple chatserver in the java ... I'm wondering about adding a username to a chat that you need to enter when you enter chat. Also, I do not understand how private messages are sent only to the addressee
If the destination is not logged in to the chat server, the error message should be sent to the sender
Each message sent by the server to the client must be accompanied by the name of the original sender and the time when the message was sent.
Java Code ---> https://dijaspora24.info/?page_id=4123
I am not going to show the implementation, since it's a big problem to solve here. However, I will give an idea of how to implement this.
I assume you know how to connect a client to a server (for example by using ServerSocket and Socket).
First, to add the username of a connected client, the server simply has to force the client enter a string to the server as the first thing when it connects to the server.
Second, create a Map to store all clients, where key is the username entered and value is the socket.
Third, when a client want to send a message to another client, some format must be used to send a string that is understandable by the server. When sending a string to another client, the username of the receiving client must be within the string. When the server receives the string, it extracts the username of the receiving client's username and locates the client in the Map by its key. As mentioned, the value of the Map element is the socket instance of the client you want to send to.
To make all of this possible, a thread must be used for each client that listens for input from each client.

Jms How to know subscriber is not alive anymore

I have a distributed system application that uses JBoss as an application server. I have a client application that serves as a simulation engine. When client is up, it sends an registration message(JMS message) to Server, then some field is set in the database. When Server is up, it sends a message ( a topic) to all clients to check that they are alive. If clients are alive, they can read message and send a response to server (queue) that it is alive.
If user close client normally, client send a message to server that I will unregister. Then server unregisters it. This is done in database side.
If user close client abnormally(kill) , then client can not send a message to server for unregistration. Then server does not know this client is not alive anymore. This causes inconsistency in my application. So I need a way to understand that client subscribed a topic is not subscribed anymore.
Server sends a message to topic to check that clients are alive.
#Schedule(hour = "*", minute = "*", second = "30", persistent = false)
public void sendNodeStatusRequest() {
Message msg = MessageFactory.createStatusRequestMessage();
publishNodeMessage(msg);
}
After a time, Server show following logs. Could I catch this warning from Java?
07:17:00,698 WARN [org.hornetq.core.protocol.core.impl.RemotingConnectionImpl] Connection failure
has been detected: Did not receive ping from /127.0.0.1:61888. It is likely
the client has exited or crashed without closing its connection, or the
network between the server and client has failed. The connection will now be closed. [code=3]
07:17:00,698 WARN [org.hornetq.core.server.impl.ServerSessionImpl] Client
connection failed, clearing up resources for session 4e4e9dc6-153e-11e7-
80fa-742b62812c29
To me the whole point of messaging system is decoupled communication. The sender (server in your case) send its stuff to the topic without actually knowing who will get the message. The clients come and go, and they should be able to read the message whenever it (still) resides in the topic.
Now from your question I understand that the server keeps track of all the connected clients by means of receiving the message back to the dedicated queue.
So I'm asking myself - maybe its something wrong with the design here.
Let me propose slightly different way of implementation.
The server should not be aware of any client, at most (because your system seems to work this way) it should know that client A, B and C are alive now only because these clients passed to the server this knowledge.
Why just don't make clients sending the "keep-alive" message every, say 1 minute (or less, depending on your needs) to the server queue without prior message from the server.
The message can include some client identifier and probably time if its not added by the infrastructure or something)
So the server will just get this message and it will keep track in memory the list of available clients along with the last time they've sent something.
So if some client disconnects "gracefully" - it can send a special message to the server like "I'm client A and consider me disconnected". Otherwise (abnormal termination/network outage/whatever) - it just won't send anything, the server will have a special process that will check whether there are stale clients on the list and if it finds them - it knows that something went wrong.
If you still want to stick with JMS way of doing, then you can try to send the message synchronously, meaning the producer will wait until it hears from the consumer. More information here : http://docs.oracle.com/javaee/6/tutorial/doc/bncfa.html

Java TCP packets via HTTP proxy

I am sending TCP packets just few bits each (one line of text or so). I am sending them to remote server via HTTP proxy however for some reason when the connection with the proxy is slow or interrupted to the server arrives just a fragment of the packet and not entire packet and it causes exceptions on the server side, how it that posible ? Is there any way on the client side how to prevent sending fragment of the packet instead of entire packet ?
Example: I am trying to send this packet:
packetHead: id (1-99)
integer: 1
short: 0
byte: 4
And in my case sometimes happens that to the server arrives just packetHead and integer and the rest of the packet is lost somewhere when the connection with the proxy is bad.
I have no access to modify server source code so I need to fix it on the client side.
Thanks for any tips.
Please show how you send your data. Every time I had a similar problem it was my fault for not flushing the stream. Especially if the stream is compressed you need to call close/complete on the GZIP or similar object to actually send out everything.

Heart-beating in STOMP client

The design of my current stomp client process is as follows:
Open stomp connection (sending CONNECT frame)
Subscribe to a feed (send a SUBSCRIBE frame)
Do a loop to continually receive feed:
while (true) {
connection.begin("txt1");
StompFrame message = connection.receive();
System.out.println("message get header"+message.toString());
LOG.info(message.getBody());
connection.ack(message, "txt1");
connection.commit("txt1");
}
My problem with this process is that I get
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)...
and I think the cause of this is mostly because the feed I am subscribed to gives information slower on certain times (as I normally get this error when the weekend comes, holidays or evenings).
I have been reading up on this here and I think this would help with my problem. However, I'm not so sure how to incorporate it with the current layout of my stomp client. Would I have to send a CONNECT header within Step 3?
I am currently using activemq to create my stomp client if that helps.
In the stomp spec we have:
Regarding the heart-beats themselves, any new data received over the
network connection is an indication that the remote end is alive. In a
given direction, if heart-beats are expected every milliseconds:
the sender MUST send new data over the network connection at least every milliseconds
if the sender has no real STOMP frame to send, it MUST send a single newline byte (0x0A)
if, inside a time window of at least milliseconds, the receiver did not receive any new data, it CAN consider the
connection as dead
because of timing inaccuracies, the receiver SHOULD be tolerant and take into account an error margin
Would that mean my client would need to send a newline bye every n seconds?
The stomp server you are connected to has timed out your connection due to innactivity.
Providing the server supports Stomp version 1.1 or newer, the easiest solution for your client is to include a heart-beat instruction in the header of your CONNECT, such as "0,10000". This tells the server that you cannot send heart-beats, but you want it to send one every 10 seconds. This way you don't need to implement them, and the server will keep the connection active by sending them to you.
Of course the server will have its own requirements of the client. In your comment it responds to your request with "1000,0". This indicates that it will send a heart-beat every 1000 millisecs, and it expects you to send one every 0 millisecs, 0 indicating none at all. So your job will be minimal.

Basic principles of a UDP server with multiple clients

I'm implementing a FTP program using UDP in Java (TCP is not an option), but I'm having trouble grasping the basics of how it's supposed to work.
As I understand, it's connectionless, so I should just have one server thread running which processes every request by any client.
Where I'm getting confused is during the actual file transfer. If the server is in the middle of a loop sending datagrams containing bits of a requested file to the client, and is waiting for an ACK from the client, but instead of that receives a completely different request from a different client, how am I supposed to handle that?
I know I could jump out of the loop to handle it, but then if the initial expected packet finally arrives, how can I pick up where I left off?
A UDP server works similar to a TCP in many respects. The major difference is that you will not receive a acknowledgement that your packets were received. You still have to know which client you are sending to, so use the DatagramSocket class. This is the Oracle tutorial for UDP: http://docs.oracle.com/javase/tutorial/networking/datagrams/index.html. It has a pretty good example in it. The significant part is getting the address and port of the original client, and returning your packets to that client:
InetAddress address = packet.getAddress();
int port = packet.getPort();
new DatagramPacket(buf, buf.length, address, port);
You could start a new thread on the server side for sending the bits every time a client sends a request. The thread would save the return address and port of the client, and die when the file send was done.

Categories