UDP is the User Datagram Protocol which is a protocol in the transport layer of TCP/IP model.We discussed the TCP/IP model earlier. We discussed the fundamentals of UDP and communication using UDP earlier. In the previous chapter we explained how java objects are transferring between two different machines on a network using UDP.In this chapter we are discussing how the Transferring file using UDP is working. File transfer with TCP is already explained.The example discussing here can be used to transfer files of type .mp3, .mp4,.jpeg etc. Any medium sized(The maximum size of a packet that can be transferred using UDP is 64 kB.If the packet size is beyond this limit,we should use TCP) media files can be transferred.
Transferring file using UDP
Our example has two applications. First one is the server and the second one is the client.The server is creating a DatagramSocket and waiting to get DatagramPacket . The client Creates an object which contains the FileEvent object.The FileEvent object contains the file content, file metadata and destination folder or directory details etc.Once the server receives a valid FileEvent object , it creates the destination path and file.The contents will be written to disk. After everything is over both the applications exits.
Let us see the FileEvent.java. A FileEvent object contains the file along with all the metadata like source path , destination path etc.The FileEvent.java should implement the Serializable interface.Then only the byte stream to object and object to byte stream conversion is going to work. Also the FileEvent.java at both the sides(client & server) should have the same serialVersionUID.
FileEvent.java
import java.io.Serializable;
public class FileEvent implements Serializable {
public FileEvent() {
}
private static final long serialVersionUID = 1L;
private String destinationDirectory;
private String sourceDirectory;
private String filename;
private long fileSize;
private byte[] fileData;
private String status;
public String getDestinationDirectory() {
return destinationDirectory;
}
public void setDestinationDirectory(String destinationDirectory) {
this.destinationDirectory = destinationDirectory;
}
public String getSourceDirectory() {
return sourceDirectory;
}
public void setSourceDirectory(String sourceDirectory) {
this.sourceDirectory = sourceDirectory;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public long getFileSize() {
return fileSize;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public byte[] getFileData() {
return fileData;
}
public void setFileData(byte[] fileData) {
this.fileData = fileData;
}
}
Now see the server application.
Server.java
import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class Server {
private DatagramSocket socket = null;
private FileEvent fileEvent = null;
public Server() {
}
public void createAndListenSocket() {
try {
socket = new DatagramSocket(9876);
byte[] incomingData = new byte[1024 * 1000 * 50];
while (true) {
DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);
socket.receive(incomingPacket);
byte[] data = incomingPacket.getData();
ByteArrayInputStream in = new ByteArrayInputStream(data);
ObjectInputStream is = new ObjectInputStream(in);
fileEvent = (FileEvent) is.readObject();
if (fileEvent.getStatus().equalsIgnoreCase("Error")) {
System.out.println("Some issue happened while packing the data @ client side");
System.exit(0);
}
createAndWriteFile(); // writing the file to hard disk
InetAddress IPAddress = incomingPacket.getAddress();
int port = incomingPacket.getPort();
String reply = "Thank you for the message";
byte[] replyBytea = reply.getBytes();
DatagramPacket replyPacket =
new DatagramPacket(replyBytea, replyBytea.length, IPAddress, port);
socket.send(replyPacket);
Thread.sleep(3000);
System.exit(0);
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void createAndWriteFile() {
String outputFile = fileEvent.getDestinationDirectory() + fileEvent.getFilename();
if (!new File(fileEvent.getDestinationDirectory()).exists()) {
new File(fileEvent.getDestinationDirectory()).mkdirs();
}
File dstFile = new File(outputFile);
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(dstFile);
fileOutputStream.write(fileEvent.getFileData());
fileOutputStream.flush();
fileOutputStream.close();
System.out.println("Output file : " + outputFile + " is successfully saved ");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.createAndListenSocket();
}
}
Now see the client application.
Client.java
import java.io.*;
import java.net.*;
public class Client {
private DatagramSocket socket = null;
private FileEvent event = null;
private String sourceFilePath = "E:/temp/images/photo.jpg";
private String destinationPath = "C:/tmp/downloads/udp/";
private String hostName = "localHost";
public Client() {
}
public void createConnection() {
try {
socket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName(hostName);
byte[] incomingData = new byte[1024];
event = getFileEvent();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(outputStream);
os.writeObject(event);
byte[] data = outputStream.toByteArray();
DatagramPacket sendPacket = new DatagramPacket(data, data.length, IPAddress, 9876);
socket.send(sendPacket);
System.out.println("File sent from client");
DatagramPacket incomingPacket = new DatagramPacket(incomingData, incomingData.length);
socket.receive(incomingPacket);
String response = new String(incomingPacket.getData());
System.out.println("Response from server:" + response);
Thread.sleep(2000);
System.exit(0);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public FileEvent getFileEvent() {
FileEvent fileEvent = new FileEvent();
String fileName = sourceFilePath.substring(sourceFilePath.lastIndexOf("/") + 1, sourceFilePath.length());
String path = sourceFilePath.substring(0, sourceFilePath.lastIndexOf("/") + 1);
fileEvent.setDestinationDirectory(destinationPath);
fileEvent.setFilename(fileName);
fileEvent.setSourceDirectory(sourceFilePath);
File file = new File(sourceFilePath);
if (file.isFile()) {
try {
DataInputStream diStream = new DataInputStream(new FileInputStream(file));
long len = (int) file.length();
byte[] fileBytes = new byte[(int) len];
int read = 0;
int numRead = 0;
while (read < fileBytes.length && (numRead = diStream.read(fileBytes, read,
fileBytes.length - read)) >= 0) {
read = read + numRead;
}
fileEvent.setFileSize(len);
fileEvent.setFileData(fileBytes);
fileEvent.setStatus("Success");
} catch (Exception e) {
e.printStackTrace();
fileEvent.setStatus("Error");
}
} else {
System.out.println("path specified is not pointing to a file");
fileEvent.setStatus("Error");
}
return fileEvent;
}
public static void main(String[] args) {
Client client = new Client();
client.createConnection();
}
}
Output
Run the server.java and then the Client.java.The source file ,destination path , host address of server are given in the Client.java. The file should be created at the specified destination , at the server side.
Remember , the maximum size of a packet that can be transferred is 84 KB . So our file size should be less than 64 KB. If our requirement is more than the limit , we need to use file transfer using TCP.
See related topics:
Fundamentals of Java networking
Transferring objects using TCP
thank u ,useful code
Thank you very much. The only code working perfect i found about this!!!
Keep up the good work
Hello. I;m trying to compile your program everything goes cool, but then when file is being send, on server side i got this output:
java.lang.ClassNotFoundException: client.FileEvent
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:625)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1612)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at Server.createAndListenSocket(Server.java:25)
at Server.main(Server.java:79)
Do you know what can make such errors?
same goes to me
Please ensure that the FileEvent is in scope of both client and server
how to put File Event is in scope of both client and server?
Dude, good code.
thnk u, nice code!
Thank you so much..
Hello if there is also a file located in the sourcefilepath with the same name. Will it be overwritten?
thankyou maan!
Im getting this error :
java.io.StreamCorruptedException: invalid stream header: 68656C6C