public void run() {
		
		initializeSocket();
		
		try {
	   		in = new BufferedInputStream(socket.getInputStream());
	   		out = new BufferedOutputStream(socket.getOutputStream());
	   		byte[] receivedData = new byte[TFTPPacket.PACKET_SIZE];
	   		
	   		getPacket(receivedData, in);

	   		if (isWRQ(receivedData)) {
	   			Util.log(Severity.REPORT, "RECEIVER: Received write request: " 
	   					+ getOpcode(receivedData));
	   			initializeOutputStream(new WRQPacket(receivedData));				

				Util.log(Severity.REPORT, "RECEIVER: Sending write request ack");
				// in this special case the ack number is 0
				AckPacket ackPacket = new AckPacket(0);
				sendPacket(ackPacket.generatePacket(), out);

				while (true) {
					
					Util.log(Severity.REPORT, "RECEIVER: Waiting for next data packet");
					
					receivedData = new byte[TFTPPacket.PACKET_SIZE];
					int bytesRead = getPacket(receivedData, in);
					Util.log(Severity.REPORT, "RECEIVER: Received " + bytesRead + " bytes");
					
					if (bytesRead != -1) {
						if (!isDataPacket(receivedData)) {

							Util.log(Severity.ERROR, "RECEIVER: Unexpected packet arrived." +
									" Expecting DATA packet, but instead got: " 
									+ getOpcode(receivedData));
							disconnect(in, out, dout);
						}
						
						DataPacket dataPacket = new DataPacket(receivedData, bytesRead);
						Util.log(Severity.REPORT, "RECEIVER packet content length: "
								+ dataPacket.getContent().length);
						Util.log(Severity.REPORT, "RECEIVER: "
								+ new String(dataPacket.getContent()));
						Util.log(Severity.REPORT, "RECEIVER data packet number: "
								+ dataPacket.getBlockNumber());
						dout.write(dataPacket.getContent());

						ackPacket = new AckPacket(dataPacket.getBlockNumber());
						sendPacket(ackPacket.generatePacket(), out);

						if (dataPacket.getContent().length + 4 < TFTPPacket.PACKET_SIZE) {
							Util.log(Severity.REPORT, "RECEIVER: File transferred");
							break;
						}
					} else {
						Util.log(Severity.REPORT, "RECEIVER: No bytes read." +
								" File must be transferred");
						break;
					}
				}
			} else {
				Util.log(Severity.ERROR, "RECEIVER: expected write but got: " 
						+ getOpcode(receivedData));
			}
		} catch (EOFException e ) {
			Util.log(Severity.ERROR, "RECEIVER: " + e.getMessage());
		} catch (IOException e ) {
			Util.log(Severity.ERROR, "RECEIVER: " + e.getMessage());
		} finally {
			disconnect(in, out, dout);
		}
   }