I have written UDP server client program. The problem that i am facing is that when i am running server program, it is not waiting for client to connect. Whole code is executing after running till the end. And when i am running client side in between of execution of server side, client side is receiving data from its point of execution. Here is my server code-
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(4321);
byte[] sendData;
String sentence = null;
FileInputStream file = new FileInputStream(new File("E:\\Deepak.txt"));
InetAddress IPAddress=InetAddress.getByName("localhost");
BufferedReader in = new BufferedReader(new InputStreamReader(file));
do{
while((sentence = in.readLine()) != null)
{
Thread.sleep(3000);
System.out.println(sentence);
sendData = sentence.getBytes();
DatagramPacket sendPacket =new DatagramPacket(sendData, sendData.length,IPAddress,9876);
serverSocket.send(sendPacket);
}
}while(true);
}
Here is my client side code-
public static void main(String args[]) throws SocketException, UnknownHostException, IOException
{
DatagramSocket clientSocket = new DatagramSocket();
byte[] receiveData = new byte[1024];
String sentence ;
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
receivePacket.getLength();
System.out.println(receivePacket.getLength());
clientSocket.receive(receivePacket);
sentence = new String( receivePacket.getData());
}
}
UDP is connectionless, so there is no such thing as a connection in it.
You can only send a packet (in a fire and forget way, send in java will send the data to the port specified in the Datagram) or receive packet on the port (receive in java will block until there is a packet received).
So you would need to implement your own connection on top of UDP if you want to have a server that only sends data if client "connects" to it.
So summing up:
send won't wait for anything, it will just throw the datagram on the wire
receive will wait for a datagram to arrive
Having the above information you would need to write your own protocol to keep the connection.
Related
I have written a client and server that are currently in an endless loop, that allow one message at a time to be sent and received. I need it to be able to continuously send/receive messages rather than be limited to one at a time.
Any idea on how I may go about this?
I am new to threads and not entirely sure how they work but i was thinking maybe a thread?
Client:
import java.io.*;
import java.net.*;
public class ClientChat {
DatagramSocket Socket;
public ClientChat(){
}
public void createAndListenSocket() throws SocketException, IOException{
while(true){
Socket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getLocalHost();
System.out.println("Type your message:");
BufferedReader message = new BufferedReader(new InputStreamReader(System.in));
byte[] incomingData = new byte[256];
String sentence = message.readLine();//"Testing from client";
byte[] data = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(data, data.length, IPAddress, 9876);
Socket.send(sendPacket);
System.out.println("Client: " + sentence);
DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);
Socket.receive(incomingPacket);
String reply = new String(incomingPacket.getData());
System.out.println("Server: " + reply);
//Socket.close();
}
}
public static void main(String[] args) throws IOException{
ClientChat client = new ClientChat();
client.createAndListenSocket();
}
}
Server:
import java.io.*;
import java.net.*;
public class ServerClient {
public void run() throws Exception{
DatagramSocket Server = new DatagramSocket(9876);
while(true){
byte[] buf = new byte[1024];
DatagramPacket incomingPacket = new DatagramPacket(buf, buf.length);
Server.receive(incomingPacket);
String message = new String(incomingPacket.getData());
System.out.println("Client: " + message);
System.out.print("Server: ");
BufferedReader response = new BufferedReader(new InputStreamReader(System.in));
String reply = response.readLine();
InetAddress IPAddress = incomingPacket.getAddress();
int port = incomingPacket.getPort();
byte[] data = reply.getBytes();
DatagramPacket replyPacket = new DatagramPacket(data, data.length, IPAddress, port);
Server.send(replyPacket);
}
}
public static void main(String[] args) throws Exception {
ServerClient Server = new ServerClient();
Server.run();
}
}
You are correct. You should use two threads - one for sending and one for receiving. You will also need two buffers to store the data while it's waiting to be send or processed after receiving. Most likely, you'll want FIFO buffers (a simple two-sided synchronized queue). Then, your main thread can only deal with reading/writing data to the queue, and the sending/receiving threads will take care of the rest in the background.
The sending thread should try to read from sending queue in a loop. The read operation on queue should block (pause the thread) until data is available.
The receiving thread should run in a loop to read a datagram from network and store it into a "received" queue. Reading datagram from network will block, while storing into a queue will return immediately unless the queue is full.
When the program is finished, you have to somehow "break" the threads from their loop. For example, you can set "shouldExit" boolean to true in your main thread, and check it in your send/receive threads. If you don't care, you can also set threads to daemon mode or just call System.exit().
Size your queues appropriately. If too small, messages will get lost and/or threads will be blocked a lot of time. If too large, you will waste memory. For example, estimate (or observe) the average and maximum number of messages in a queue, and add a safety margin.
I try to read the UDP Stream from X-Plane 12 in Java.
This is what I try:
public class EchoClient {
#Test
public void echo() throws IOException {
DatagramSocket socket;
InetAddress address;
byte[] buf;
socket = new DatagramSocket();
address = InetAddress.getByName("localhost");
String msg = "TEST";
buf = msg.getBytes();
DatagramPacket packet
= new DatagramPacket(buf, buf.length, address, 49000);
socket.send(packet);
packet = new DatagramPacket(buf, buf.length);
System.out.println("hi there");
while(true) {
socket.receive(packet); // it "stops" here... without an error
String received = new String(
packet.getData(), 0, packet.getLength());
System.out.println(received);
}
}}
X-Plane is running and the UDP option is activated - but my program does print nothing on the console.. and it is runnig forever (while true)
Receive is blocked and waiting to a receive a packet. The packet you sent earlier is dropped on the floor because no one is listening.
I have a project require using UDP protocol to transfer file but still guaranty the feature of TCP protocol. That means we have the speed of UDP and the file not lost.
I've already have:
Server:
public class UDPServer {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
// TODO code application logic here
int port = 6788;
DatagramSocket sk = new DatagramSocket(port);
byte[] buf = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buf, buf.length);
sk.receive(request);
String msg = (new String(request.getData()));
DatagramPacket reply = new DatagramPacket(msg.getBytes(), msg.getBytes().length, request.getAddress(), request.getPort());
sk.send(reply);
}
}
}
Client:
public class UDPClient {
public static void main(String[] args) throws SocketException, UnknownHostException, IOException {
DatagramSocket sk = new DatagramSocket();
String msg = "message send";
InetAddress addr = InetAddress.getByName("localhost");
int port = 6788;
DatagramPacket request = new DatagramPacket(msg.getBytes(), msg.getBytes().length, addr, port);
sk.send(request);
byte[] buf = new byte[1000];
DatagramPacket reply = new DatagramPacket(buf, buf.length);
sk.receive(reply);
System.out.println("packet da nhan duoi client" + new String(reply.getData()));
sk.close();
}
}
and can you help me any suggest to guaranty file not lost ?. tks
You have quite big task, if you really want to implement fast and reliable file transfer with UDP.
With very small files (that fits in a single IP packet), it could be easy to avoid some overhead of TCP (like TCP connection opening and closing handshakes).
But If you are going to transfer bigger files, then you must implement many difficult features, like: flow control, selective acknowledges, re-transmissions and so on.
So I suggest to use TCP, instead of implementing own similar protocol.
You just CAN'T. It's not designed to be reliable.
If you manage to do it... it just means that you've implemented TCP yourself!, it will be much slower though.
I'm devolping an SMS application that uses UDP protocol . My application need to do the following , client send to another client a message doesn't exceed 160 and he/she know the other client IP address . It will send through a server which will save it in case client is offline .
I started working on it but then I stopped ! I was having problem with these things .
How can multiple clients sends to server ? I searched about and I read about something called mutithreading , can anyone explain or give me example for it ?
also , I couldn't imagin the process of taking messages from clients and then saving it . I mean how the server know which message belong to which client ?
this is the code which I'm working on it
server :
import java.io.*;
import java.net.*;
class Server {
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(9876);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true)
{
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
String senderSentence = "From "+IPAddress+" Msg "+sentence;
sendData = senderSentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress,
port);
serverSocket.send(sendPacket);
} } }
client :
import java.io.*;
import java.net.*;
public class Client {
public static void main(String args[]) throws Exception
{
String sentence;
BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
do {
System.out.println("Enter a msg , NOTE: don't exceed 160 charcter");
sentence = inFromUser.readLine();
}
while(sentence.length() >= 160);
System.out.println("Enter the adress of the other user");
String ip=inFromUser.readLine();
InetAddress IPAddress = InetAddress.getByName(ip);
sendData = sentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence =
new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
} }
Thank you ~
I'm not sure why you need to use UDP - but if this isn't some special requirement you might want to look at using a web server.
I quite like the Play Framework for Java, which is going to handle the threading for you. Every time you send a message to the server it is just like sending a request for a web page, so you can reply with JSON or XML or whatever you think is best.
This is going to be a lot easier than handling all the socket communication yourself - but as I say, maybe you have a special requirement.
Hope this helps!
I have to send a UDP packet and get a response back from UDP server. I though UDP was analogous with a java.net.DatagramPacket in Java, but the documentation for DatagramPacket seems to be that you send a packet but don't get anything back, is this the right thing to use or should I be using java.net.Socket
Example of UDP datagram sending and receiving (source):
import java.io.*;
import java.net.*;
class UDPClient
{
public static void main(String args[]) throws Exception
{
BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = inFromUser.readLine();
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
}
}
You have to use a DatagramPacket and a DatagramSocket. When you send a packet you just send a packet. However when you receive a packet you can get a packet which was sent from another program (e.g. the servers reply)
http://docs.oracle.com/javase/7/docs/api/java/net/DatagramSocket.html
Socket is only for TCP connections.
The Java documentation does cover how to write a client and a server.
http://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html
You want to look at DatagramSocket#receive
That's precisely the distinction between UDP and TCP sockets.
UDP is broadcast, whereas TCP with java.net.Socket is point to point. UDP is fire-and-forget, analogous to publishing a message on a JMS Topic.
See: http://docs.oracle.com/javase/tutorial/networking/datagrams/index.html