package Main;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.net.*;
import java.util.ArrayList;
import java.io.*;
/**
*
* @author phihai
*/
public class BroadCast {
DatagramSocket utpSocket;
ArrayList<Networks> arr_nw = new ArrayList<Networks>();
public BroadCast(){}
public BroadCast(int Port)
{
try
{
utpSocket = new DatagramSocket(Port);
Readmap();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void send(BC_Packet pk,Networks nw ) // sned thông tin cho tất cả các client
{
try
{
byte[] buf = serialize(pk);
DatagramPacket packet = new DatagramPacket(buf, buf.length, nw.GetAddress(), nw.GetPort());
utpSocket.send(packet);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void sendBroadCast(BC_Packet pk) // hàm dùng để gửi thông tin pk cho các clien trong node.map
{
for(int i=0;i<arr_nw.size();i++)
{
send(pk,arr_nw.get(i));
}
}
private void Readmap() // hàm đọc thông tin node.map
{
try
{
String str ;
String [] array;
int port;
BufferedReader br = new BufferedReader(new FileReader("nodes.map"));
int count = Integer.parseInt(br.readLine());
for(int i=0;i<count;i++)
{
str = br.readLine();
array = str.split(" ");
port = Integer.parseInt(array[2]);
arr_nw.add(new Networks(InetAddress.getByName(array[1]),port)); // arr_nw lấy thông tin IP + port
}
while ((str = br.readLine()) != null)
{
array = str.split(" "); // lấy thông tin cost -> chưa làm
//System.out.println("Id: "+array[0] + " IP: "+array[1] +" Port: "+array[2]);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
protected void startListenerThread() // tạo cổng lắng nghe
{
ReceiveRP thread = new ReceiveRP(utpSocket);
thread.start();
}
public byte[] serialize(Object obj) throws IOException // chuyển các object thành dạng byte để tiến hành gửi thông tin
{
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
objectStream.writeObject(obj);
objectStream.flush();
return byteStream.toByteArray();
}
}
class BC_Packet implements Serializable // lưu thông tin broadcast cần thiết cho việc gửi gói tin
{
private int Flag;
private String msg;
private int part;
private String filename;
private byte[] data;
private int fileSize;
private long headerlength;
private int Sequence;
private int Acknowledge;
public BC_Packet(){}
public BC_Packet(int Flag,int part,String msg)
{
this.Flag = Flag;
this.part = part;
this.msg = msg;
}
public int getFlag() {
return Flag;
}
public void setFlag(int Flag) {
this.Flag = Flag;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getPart() {
return part;
}
public void setPart(int part) {
this.part = part;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public long getHeaderlength() {
return headerlength;
}
public void setHeaderlength(long headerlength) {
this.headerlength = headerlength;
}
public int getSequence() {
return Sequence;
}
public void setSequence(int Sequence) {
this.Sequence = Sequence;
}
public int getAcknowledge() {
return Acknowledge;
}
public void setAcknowledge(int Acknowledge) {
this.Acknowledge = Acknowledge;
}
public int getFileSize() {
return fileSize;
}
public void setFileSize(int fileSize) {
this.fileSize = fileSize;
}
}
class ReceiveRP extends Thread // nhận thông tin broadcast
{
DatagramSocket socket;
BroadCast bc = new BroadCast();
BC_Packet pk;
Chunks ck = new Chunks();
byte[] Buf = new byte[1500];
DatagramPacket Packet;
byte [] Chunks = new byte[1024*512];
public ReceiveRP(DatagramSocket socket)
{
this.socket = socket;
}
public void run()
{
while(true)
{
try
{
Packet = new DatagramPacket(Buf, Buf.length);
socket.receive(Packet);
pk = (BC_Packet) deserialize(Packet.getData()); // tiến hành phân giải byte ra dạng object ( cụ thể là cho ra object thuộc class BC_Packet)
if(pk.getFlag() == 0)// tìm chunks
{
String name = ck.Check_Chunks(pk.getMsg());
pk.setFlag(1);
if(name.equals("")) // nếu không tìm thấy chunks
{
pk.setMsg(" ");
}
else
{
pk.setMsg(name);
}
SendPacket();
}
else if(pk.getFlag() == 1)
{
if(!pk.getMsg().equals(" "))
{
pk.setFlag(2);
pk.setFilename(pk.getMsg());
}
SendPacket();
}
else if(pk.getFlag() == 2)// read file
{
File file = new File("Share\\"+pk.getFilename());
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
int size = (int) file.length();
byte[] buffer = new byte[1024];
int n;
int downloaded = 0;
while((n = bis.read(buffer,0,buffer.length)) != -1)
{
downloaded += n; // số lượng byte đọc được
pk.setSequence(pk.getAcknowledge());
pk.setAcknowledge(downloaded);
pk.setFileSize(size);
pk.setData(buffer);
pk.setFlag(3);
System.out.println(buffer);
SendPacket(); // gửi packet
}
bis.close();
pk.setFlag(-1); // thoát khỏi quá trình truyền file
}
else if(pk.getFlag() == 3)// tìm chunks
{
System.out.println(pk.getFilename()+" "+pk.getSequence()+" "+pk.getAcknowledge()+" "+pk.getFileSize());
System.arraycopy(pk.getData(),0,Chunks,pk.getSequence(),pk.getData().length); // ghép mảng pk.getdata(1024 bytes) nhận được vào mảng Chunks (512*1024)
if(pk.getAcknowledge() == pk.getFileSize())
{
File file = new File("Share\\"+pk.getFilename());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
//out.write(Chunks,0,pk.getAcknowledge()); // tiến hành ghi file
out.write(Chunks,0,pk.getFileSize()); //sửa lại
out.flush();
out.close();
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
private void SendPacket()throws IOException
{
byte[] buf = bc.serialize(pk); // chuyển object (pk)-> packet sang dạng byte
Packet = new DatagramPacket(buf, buf.length,Packet.getAddress(), Packet.getPort());
socket.send(Packet);
}
private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException // hàm chuyển đổi thông tin byte nhận được sang object
{
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
ObjectInputStream objectStream = new ObjectInputStream(byteStream);
return objectStream.readObject();
}
}
class Networks{ // các thông tin của mạng trong file node.map
private InetAddress address;
private int port;
private int cost; // chưa lấy thông tin cost ở đây
public Networks(InetAddress address,int port)
{
this.address = address;
this.port = port;
}
public InetAddress GetAddress()
{
return address;
}
public void SetAddress(InetAddress address)
{
this.address = address;
}
public int GetPort()
{
return port;
}
public void SetPort(int port)
{
this.port = port;
}
public int GetCost()
{
return cost;
}
public void SetCost(int cost)
{
this.cost = cost;
}
}