I have a problem with a Sender and a Server UDP. The SenderUDP sends an object and the ServerUDP must receive it. For the first object all works fine, but when I try to send another object the server throws a StreamCorruptedException.
Here the client side code:
public class SenderUDP implements Runnable {
private java.net.DatagramSocket clientsocket;
private ObjectOutputStream out;
private int port;
private InetAddress ip;
private Packet objToSend;
private ByteArrayOutputStream baos;
public SenderUDP(String ip, int port, Packet p) throws UnknownHostException{
this.ip =InetAddress.getByName(ip);
this.port = port;
this.objToSend = p;
this.out = null;
this.clientsocket = null;
}
@Override
public void run(){
try{
clientsocket = new DatagramSocket ();
System.out.println("Inside senderUDP");
byte[] sendData;
baos = new ByteArrayOutputStream(1024);
out = new ObjectOutputStream(baos);
out.writeObject(objToSend);
sendData = baos.toByteArray();
DatagramPacket sendpacket = new DatagramPacket(sendData,sendData.length,ip,port);
clientsocket.send(sendpacket);
System.out.println("Sended packet with UDP");
out.flush();
if(this.objToSend.getOP() == 1){
byte[] buf = new byte[1024];
int read;
ByteArrayOutputStream bas = new ByteArrayOutputStream((int)this.objToSend.getFile().length());
FileInputStream fis = new FileInputStream(objToSend.getFile());
while((read = fis.read(buf)) != -1){
bas.write(buf, 0, read);
}
DatagramPacket sendfile = new DatagramPacket(bas.toByteArray(), bas.toByteArray().length, ip, port);
clientsocket.send(sendfile);
}
out.close();
}
catch(UnknownHostException uhe) {
System.err.println(uhe.getMessage());
}
catch(IOException ioe) {
System.err.println(ioe.getMessage());
}
}
}
Here is the server side code:
class ServerUDP implements Runnable {
private DatagramSocket socket;
private int port;
private Controller controller;
private byte[] buffer;
private DatagramPacket packet;
private Packet p;
private ObjectInputStream ois;
public ServerUDP(int port, Controller controller){
this.socket = null;
this.port = port;
this.controller = controller;
}
@Override
public void run() {
try {
socket = new DatagramSocket(port);
} catch (SocketException ex) {
Logger.getLogger(ServerUDP.class.getName()).log(Level.SEVERE, null, ex);
}
while(true){
buffer = new byte[1000000];
packet = new DatagramPacket(buffer,buffer.length);
System.out.println("Ascolto UDP!");
try {
socket.receive(packet);
System.out.println(packet);
System.out.println("1");
} catch (IOException ex) {
Logger.getLogger(ServerUDP.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Packet UDP Received!");
try {
ois = new ObjectInputStream(new ByteArrayInputStream(buffer));
} catch (IOException ex) {
Logger.getLogger(ServerUDP.class.getName()).log(Level.SEVERE, null, ex);
}
try {
p = (Packet) ois.readObject();
System.out.println("Pacchetto/Evento arrivato con UDP!");
System.out.println(p);
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(ServerUDP.class.getName()).log(Level.SEVERE, null, ex);
}
if(p.getOP() == 1){
Thread t = new Thread(new FilesManager(socket,p,false, controller));
t.start();
}
controller.enqueue(p);
try {
ois.close();
} catch (IOException ex) {
Logger.getLogger(ServerUDP.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
The StreamCorruptedException is thrown by
ois = new ObjectInputStream(new ByteArrayInputStream(buffer));
and
p = (Packet) ois.readObject();
Thanks!
Umm, you totally forgot to implement a protocol! You forgot to do transmit pacing, duplicate datagram detection, checksums, datagram reordering, retransmissions, acknowledgements, slow start, sliding windows, and pretty much everything else! You may not absolutely need all of these things, but you need most of them or you need to accomplish these basic functions some other way.
You’ve done about 1% of the job of sending data using UDP. It won’t work until you finish the job.
If you want minimal file transfer over UDP, then TFTP is what you want to study. Here’s a description of how a file transfer occurs over UDP:
This avoids the need to do transmit pacing, slow start, windows, or datagram reordering by only keeping one chunk of data “in flight” at a time. That makes it very slow, but also pretty simple. As described above, you can at best exchange 512 bytes per round trip time.