Related
My client:
class Read_ChatClient extends Thread{
private static Socket client;
private String user;
static ArrayList<SingleChatF> chatFrames = new ArrayList<>();
public Read_ChatClient(Socket client, String username) {
this.client = client;
this.user = username;
}
public void checkAddNewFrame(String sourceName, String desName, String mess){
boolean exitFrame = false;
int index = 0;
for(SingleChatF frame: chatFrames) {
System.out.println(index + "; " + frame.getSourceName() + "; " + frame.getDestName());
if (frame.Match(sourceName, desName)) {
frame.gettxtchatall().append(mess + "\n");
System.out.println("Founded frame: " + sourceName + "; " + desName);
exitFrame = true;
break;
};
index++;
}
if(!exitFrame) {
SingleChatF newFrame = new SingleChatF(this.client, sourceName, desName);
newFrame.setVisible(true);
newFrame.gettxtchatall().append(mess + "\n");
chatFrames.add(newFrame);
System.out.println("Created new frame: " + sourceName + "; " + desName);
}
}
#Override
public void run(){
System.out.println(new Date().getTime() + " - Read_ChatClient");
DataInputStream dis = null;
try {
dis = new DataInputStream(client.getInputStream());
System.out.println(" - Read_ChatClient client.getInputStream() OK");
while(true) {
System.out.println(" - Read_ChatClient......");
String sms = dis.readUTF();
System.out.println(" - Read_ChatClient.sms: "+sms);
if (sms.contains("login_successed")){
System.out.println(" - Read_ChatClient: Join()");
String[] info = sms.split(";");
String username = info[1];
String[] onlineuserList = info[2].split(",");
if (username.equalsIgnoreCase(user)) {
MultiThreads_LoginClient.setLoginF(false);
MultiThreads_LoginClient.chatFrame = new ChatF(user, client);
MultiThreads_LoginClient.chatFrame.setVisible(true);
JTable OnlineTab = MultiThreads_LoginClient.chatFrame.getjtableonlineuser();
DefaultTableModel model = (DefaultTableModel) OnlineTab.getModel();
for (String name : onlineuserList) {
model.addRow(new String[]{name});
}
}else if(!username.equalsIgnoreCase(user)){
MultiThreads_LoginClient.chatFrame.getjtableonlineuser().setModel(new DefaultTableModel(null,new String[]{"Online Users"}));
for (String name : onlineuserList) {
JTable OnlineTab = MultiThreads_LoginClient.chatFrame.getjtableonlineuser();
DefaultTableModel model = (DefaultTableModel) OnlineTab.getModel();
model.addRow(new String[]{name});
}
MultiThreads_LoginClient.chatFrame.gettxtchatall().append(username+" da ket noi\n");
}
} else if (sms.contains("login_failed;")) {
JOptionPane.showMessageDialog(null, "Login Failed");
} else if (sms.contains("user_actived")) {
JOptionPane.showMessageDialog(null, "User's activing");
}else if(sms.contains("updateOnlineUserList")){
String[] list = sms.split(":");
String[] newList = list[1].split(",");
MultiThreads_LoginClient.chatFrame.getjtableonlineuser().setModel(new DefaultTableModel(null,new String[]{"Online Users"}));
for (String name : newList) {
JTable OnlineTab = MultiThreads_LoginClient.chatFrame.getjtableonlineuser();
DefaultTableModel model = (DefaultTableModel) OnlineTab.getModel();
model.addRow(new String[]{name});
}
System.out.println("updateOnlineUserList:"+sms);
}else if(sms.contains("chatPrivate")){
//{ChatPrivate}:{Source_name}:{des_name}:{mess}:{host:port}
System.out.println("ClientRead_chatPrivate: " + sms);
String[] content = sms.split(";");
String sourceName = content[1];
String desName = content[2];
String mess = content[3];
checkAddNewFrame(desName, sourceName, mess);
}else if(sms.contains("AlertAlert_SendFilesToClient")){
System.out.println("AlertAlert_SendFilesToClient");
currentThread().wait();
Read_FileClient rf = new Read_FileClient(client);
rf.start();
}else{
MultiThreads_LoginClient.chatFrame.gettxtchatall().append("\n" + sms);
System.out.println(sms);
}
}
} catch (Exception e) {
try {
currentThread().wait();
Read_FileClient rf = new Read_FileClient(client);
rf.start();
//dis.close();
} catch (InterruptedException ex) {
Logger.getLogger(Read_ChatClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}}
My Server:
class Read_ChatServer extends Thread{
private static Socket socket;
private static SingleChatFrame_SV singlechatFrame;
public static void setsocket(Socket socket){
Read_ChatServer.socket = socket;
}
public Read_ChatServer(Socket client) {
this.socket = client;
}
#Override
public void run(){
System.out.println("Read_ChatServer");
DataInputStream dis = null;
DataOutputStream dos = null;
try {
System.out.println("Checking socket.getInputStream()");
dis = new DataInputStream(socket.getInputStream());
System.out.println("OK socket.getInputStream()");
while (true) {
String sms = dis.readUTF();
System.out.println(" - Read_ChatServer: " + sms);
if (sms.contains("Login_Requiere")) {
//{Login_Requiere};{username};{password}
try {
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
System.out.println("Trying login for user " + sms);
String[] contents = sms.split(";");
String info[] = sms.split(";");//info[1]: username - info[2]:pass
Connection con = DBConnection.getConnection();
String query = "Select *from `info` where `user`=? AND `pw`=?";
PreparedStatement pst;
ResultSet rs;
try {
pst = con.prepareStatement(query);
pst.setString(1, info[1]);
pst.setString(2, info[2]);
rs = pst.executeQuery();
if (rs.next()) {
// login;{success: true, onlineuser: ["", ""]}
// chat;
if (!MultiThreads_LoginServer.checkuserexits(info[1])) {
accountinfo temp = new accountinfo(socket, info[1]);
MultiThreads_LoginServer.chatFrame_Server.gettxtchatall().append("Da ket noi " + info[1] + "\n");
System.out.println("Da ket noi " + socket);
MultiThreads_LoginServer.accountinfoList.add(temp);
showonlineuser();
String statusString = "login_successed;" + info[1] + ";" + MultiThreads_LoginServer.convertoString();
BroadCastUserListToAllClients wu = new BroadCastUserListToAllClients(statusString);
wu.start();
} else {
dos.writeUTF("user_actived; ; ");
}
} else {
dos.writeUTF("login_failed; ; ");
//dos.flush();
}
} catch (SQLException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
DBConnection.closeConnection(con);
MultiThreads_LoginServer.chatFrame_Server.gettxtchatall().append("User: " + info[1] + "\tPass: " + info[2] + "\n");
} catch (Exception e) {
System.out.println(" - Error Read_LoginServer: " + e.getMessage());
try {
dis.close();
dos.close();
socket.close();
} catch (IOException ex) {
Logger.getLogger(Read_LoginServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}else if (sms.contains("exit")) {
String[] exitInfo = sms.split(":");
String notify = "Ngat ket noi voi : " + exitInfo[1]+"\n";
try {
MultiThreads_LoginServer.remove_user(exitInfo[1]);
if (MultiThreads_LoginServer.accountinfoList.isEmpty()) {
MultiThreads_LoginServer.chatFrame_Server.gettxtchatall().append("No User Online!");
} else {
showonlineuser();
MultiThreads_LoginServer.chatFrame_Server.gettxtchatall().append(notify + "\n");
System.out.println(" - Read_ChatServer: " + notify);
for (accountinfo item : MultiThreads_LoginServer.accountinfoList) {
dos = new DataOutputStream(item.socket.getOutputStream());
dos.writeUTF(notify);
//dos.flush();
}
}
String currentList = convertoString();
BroadCastUserListToAllClients broad = new BroadCastUserListToAllClients("updateOnlineUserList: " + currentList);
broad.start();
} catch (Exception e) {
showonlineuser();
MultiThreads_LoginServer.chatFrame_Server.gettxtchatall().append(notify + "\n");
MultiThreads_LoginServer.chatFrame_Server.gettxtchatall().append("No User Online!");
}
} else if(sms.contains("chatPrivate")){
System.out.println("server_chatPrivate: "+ sms);
//{ChatPrivate};{Source_name};{des_name};{mess}
String[] content = sms.split(";");
String s_name = content[1];
String d_name = content[2];
if(d_name.equalsIgnoreCase("Server")){
//
}else{
for(accountinfo item:MultiThreads_LoginServer.accountinfoList){
if(item.username.equalsIgnoreCase(d_name)){
dos = new DataOutputStream(item.socket.getOutputStream());
dos.writeUTF(sms);
}
}
}
}else if(sms.contains("Alert_SendFiles")){
System.out.println("Alert_SendFiles");
String[] content = sms.split(":");
String des_name = content[1];
AlertAlert_SendFilesToClient alert = new AlertAlert_SendFilesToClient(des_name);
alert.start();
Thread.sleep(1000);
System.out.println("-Alert_SendFiles: pass alert");
currentThread().wait();
Read_FileServer rf = new Read_FileServer(socket);
rf.start();
}else{
MultiThreads_LoginServer.chatFrame_Server.gettxtchatall().append(sms + "\n");
for (accountinfo item : MultiThreads_LoginServer.accountinfoList) {
dos = new DataOutputStream(item.socket.getOutputStream());
dos.writeUTF(sms);
//dos.flush();
}
}
}
} catch (Exception e) {
System.out.println("No user online!");
System.out.println(" - Error Read_ChatServer: " + e.getMessage());
try {
dis.close();
//dos.close();
} catch (IOException ex) {
System.out.println(" - Error Read_ChatServer: " + ex.getMessage());
Logger.getLogger(Read_ChatServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}}
My class Send file:
class Write_SendFiles extends Thread{
private Data_file data;
private Socket client;
public Write_SendFiles(Data_file data,Socket client) {
this.data = data;
this.client = client;
}
#Override
public void run() {
System.out.println("Write_SendFiles");
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(client.getOutputStream());
System.out.println("-Write_SendFiles:"+data.getfilename());
oos.writeObject(data);
System.out.println("-Write_SendFiles: pass send file");
} catch (IOException ex) {
/*try {
oos.close();
} catch (IOException ex1) {
System.out.println("-Write_SendFiles Err:"+ex.getMessage());
Logger.getLogger(Write_SendFiles.class.getName()).log(Level.SEVERE, null, ex1);
}*/
System.out.println("-Write_SendFiles Err:"+ex.getMessage());
Logger.getLogger(Write_SendFiles.class.getName()).log(Level.SEVERE, null, ex);
}
} }
class Read_FileClient extends Thread{
private Socket client;
public Read_FileClient(Socket client) {
this.client = client;
}
#Override
public void run() {
System.out.println("Client file");
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(client.getInputStream());
System.out.println("-Server file: pass new obj");
try {
Data_file datafile = (Data_file) ois.readObject();
System.out.println("-Server file:read file successfully");
boolean exitingChatFrame_file = false;
for (SingleChatF single : Read_ChatClient.chatFrames) {
exitingChatFrame_file = single.Match(datafile.getdes_name(), datafile.getdes_name());
System.out.println("File - Finding frame: Source=" + datafile.getdes_name() + "; Dest=" + datafile.getdes_name() + "; " + exitingChatFrame_file);
if (exitingChatFrame_file) {
JList FilesTranfer = single.getjlisttranfer();
DefaultListModel model = new DefaultListModel();
FilesTranfer.setModel(model);
model.addElement(datafile);
System.out.println("Founded");
single.gettxtchatall().append("Getting file...");
break;
}
}
if (!exitingChatFrame_file) {
System.out.println("ClientRead_chatPrivate: not active");
SingleChatF newFrame = new SingleChatF(this.client, datafile.getdes_name(), datafile.getdes_name());
newFrame.setVisible(true);
JList FilesTranfer = newFrame.getjlisttranfer();
DefaultListModel model = new DefaultListModel();
FilesTranfer.setModel(model);
model.addElement(datafile);
chatFrames.add(newFrame);
newFrame.gettxtchatall().append("Getting file...");
}
//client.close();
} catch (ClassNotFoundException ex) {
Logger.getLogger(Read_ChatClient.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (IOException ex) {
Logger.getLogger(Read_FileClient.class.getName()).log(Level.SEVERE, null, ex);
}
}}
My Server read file:
class Read_FileServer extends Thread{
private Socket client;
public Read_FileServer(Socket client) {
this.client = client;
}
#Override
public void run() {
System.out.println("Server Read_FileServer");
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
ois = new ObjectInputStream(client.getInputStream());
try {
Data_file datafile = (Data_file)ois.readObject();
System.out.println("-Server Read_FileServer: read file successfully");
for(accountinfo item : MultiThreads_LoginServer.accountinfoList){
if(item.username.equalsIgnoreCase(datafile.getdes_name())){
oos = new ObjectOutputStream(item.socket.getOutputStream());
oos.writeObject(datafile);
}
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(Read_FileServer.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (IOException ex) {
try {
ois.close();
oos.close();
} catch (IOException ex1) {
Logger.getLogger(Read_FileServer.class.getName()).log(Level.SEVERE, null, ex1);
}
Logger.getLogger(Read_FileServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
But now i have the function is send file. So i have to use ObjectInputStream and Object OutputStream .The problems is 2 type difference between DataInputStream,DataOutputStream and ObjectInputStream,OutputStream.How can i put thread of ObjectInputStream and ObjectOutputStreadm to my class. thanks you!
try (DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStreamdos = new DataOutputStream(socket.getOutputStream())){
System.out.println("Trying login for user " + sms);
String[] contents = sms.split(";");
String info[] = sms.split(";");//info[1]: username - info[2]:pass
Connection con = DBConnection.getConnection();
String query = "Select *from `info` where `user`=? AND `pw`=?";
PreparedStatement pst;
ResultSet rs;
try {
pst = con.prepareStatement(query);
pst.setString(1, info[1]);
pst.setString(2, info[2]);
rs = pst.executeQuery();
if (rs.next()) {
// login;{success: true, onlineuser: ["", ""]}
// chat;
if (!MultiThreads_LoginServer.checkuserexits(info[1])) {
accountinfo temp = new accountinfo(socket, info[1]);
MultiThreads_LoginServer.chatFrame_Server.gettxtchatall().append("Da ket noi " + info[1] + "\n");
System.out.println("Da ket noi " + socket);
MultiThreads_LoginServer.accountinfoList.add(temp);
showonlineuser();
String statusString = "login_successed;" + info[1] + ";" + MultiThreads_LoginServer.convertoString();
BroadCastUserListToAllClients wu = new BroadCastUserListToAllClients(statusString);
wu.start();
} else {
dos.writeUTF("user_actived; ; ");
}
} else {
dos.writeUTF("login_failed; ; ");
//dos.flush();
}
} catch (SQLException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
DBConnection.closeConnection(con);
MultiThreads_LoginServer.chatFrame_Server.gettxtchatall().append("User: " + info[1] + "\tPass: " + info[2] + "\n");
} catch (Exception e) {
System.out.println(" - Error Read_LoginServer: " + e.getMessage());
}
I am sending mails with interval from my swing program. I want to show progress bar when button to send emails is clicked. When all emails are sent, progress bar reaches to 100% complete. But progrssbar doesn't show anything while mails are going.
private void btnSendEmailsNowActionPerformed(java.awt.event.ActionEvent evt) {
btnSendEmailsNow.setEnabled(false);
Task task = new Task();
task.start();
//Load property files
loadProps();
//Read config file.
readConfig();
//Take filename "FromEmail_list" after reading config file.
BufferedReader br1=null;
BufferedReader br2=null;
String line1="",line2="";
String csvSplitBy=",";
String strMailFrom="",strPassword="";
String strSendTo="";
int countCSVFrom=0,countCSVSendTo;
System.out.println("strCSVFrom=" + strCSVFrom + ", strcsvSendTo=" + strCSVSendTo);
try{
br1=new BufferedReader(new FileReader(strCSVFrom));
br2=new BufferedReader(new FileReader(strCSVSendTo));
while((line1=br1.readLine())!=null){
countCSVFrom+=1;
String[] strarrFromEmail = line1.split(csvSplitBy);
strMailFrom=strarrFromEmail[0];
strPassword=strarrFromEmail[1];
System.out.println("strFrom="+strMailFrom + ", strPassword="+strPassword);
countCSVSendTo=0;
while((line2=br2.readLine())!=null){
System.out.println("line2="+line2.toString());
countCSVSendTo+=1;
String[] strMailTo=line2.split("\n");
strSendTo=strMailTo[0];
String subject = "Test mail";
String message="";
//inline image
Map<String,String> inlineImage=new HashMap<String,String>();
inlineImage.put("image1", "Logo.jpg");
frmEmailer mailer = new frmEmailer();
String filename=txtHTMLFile.getText();
System.out.println("filename=" + filename);
try{
message=mailer.readHTML(filename,message);
mailer.sendHtmlEmail(strhost, strport, strMailFrom, strPassword, strSendTo,
subject, message,inlineImage);
System.out.println("Email sent successfully.");
Random rand = new Random();
int randomNum = rand.nextInt((8 - 3) + 1) + 3;
System.out.println(randomNum);
Thread.sleep(randomNum*1000); //1000 microseconds = 1 seconds.
if(countCSVSendTo==2){
break;
}
}catch (Exception ex) {
System.out.println("Failed to sent email.");
ex.printStackTrace();
}
}
//System.out.println("countcsvfrom="+countCSVFrom + ", line1=" + line1.toString());
System.out.println("countcsvsendto="+countCSVSendTo);
}
JOptionPane.showMessageDialog(null, "Emails sent successfully!");
btnSendEmailsNow.setEnabled(true);
}catch(FileNotFoundException fnfe){
fnfe.printStackTrace();
JOptionPane.showMessageDialog(null, "Failed to send Email!");
}catch(IOException ioe ){
JOptionPane.showMessageDialog(null, "Failed to send Email!");
ioe.printStackTrace();
}
}
private class Task extends Thread {
public Task(){
}
public void run(){
for(int i =0; i<= 100; i+=10){
final int progress = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progressbar.setValue(progress);
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
}
Try this code :
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
new Thread(){
public void run(){
btnSendEmailsNow.setEnabled(false);
//Load property files
loadProps();
//Read config file.
readConfig();
//Take filename "FromEmail_list" after reading config file.
BufferedReader br1=null;
BufferedReader br2=null;
String line1="",line2="";
String csvSplitBy=",";
String strMailFrom="",strPassword="";
String strSendTo="";
int countCSVFrom=0,countCSVSendTo;
int EmailCount = 0;
ProgressMonitor pm = new ProgressMonitor(null, "Loading Progress", "Getting Started...", 0, /*number of emails to be sent*/);
System.out.println("strCSVFrom=" + strCSVFrom + ", strcsvSendTo=" + strCSVSendTo);
try{
br1=new BufferedReader(new FileReader(strCSVFrom));
br2=new BufferedReader(new FileReader(strCSVSendTo));
while((line1=br1.readLine())!=null){
countCSVFrom+=1;
String[] strarrFromEmail = line1.split(csvSplitBy);
strMailFrom=strarrFromEmail[0];
strPassword=strarrFromEmail[1];
System.out.println("strFrom="+strMailFrom + ", strPassword="+strPassword);
countCSVSendTo=0;
while((line2=br2.readLine())!=null){
System.out.println("line2="+line2.toString());
countCSVSendTo+=1;
String[] strMailTo=line2.split("\n");
strSendTo=strMailTo[0];
String subject = "Test mail";
String message="";
//inline image
Map<String,String> inlineImage=new HashMap<String,String>();
inlineImage.put("image1", "Logo.jpg");
frmEmailer mailer = new frmEmailer();
String filename=txtHTMLFile.getText();
System.out.println("filename=" + filename);
try{
message=mailer.readHTML(filename,message);
mailer.sendHtmlEmail(strhost, strport, strMailFrom, strPassword, strSendTo,
subject, message,inlineImage);
System.out.println("Email sent successfully.");
EmailCount++;
pm.setProgress(EmailCount);
pm.setNote("Sent " + EmailCount + " Mails.");
Random rand = new Random();
int randomNum = rand.nextInt((8 - 3) + 1) + 3;
System.out.println(randomNum);
Thread.sleep(randomNum*1000); //1000 microseconds = 1 seconds.
if(countCSVSendTo==2){
break;
}
}catch (Exception ex) {
System.out.println("Failed to sent email.");
ex.printStackTrace();
}
}
//System.out.println("countcsvfrom="+countCSVFrom + ", line1=" + line1.toString());
System.out.println("countcsvsendto="+countCSVSendTo);
}
JOptionPane.showMessageDialog(null, "Emails sent successfully!");
btnSendEmailsNow.setEnabled(true);
}catch(FileNotFoundException fnfe){
fnfe.printStackTrace();
JOptionPane.showMessageDialog(null, "Failed to send Email!");
}catch(IOException ioe ){
JOptionPane.showMessageDialog(null, "Failed to send Email!");
ioe.printStackTrace();
}
}
}.start();
}
You can easily do that thing with ProgressMonitor
I have manage to write a async class that send a picture over broadcast and wait for clients inverse ack and then send the packages that were not received...
The issue I am facing is that for sending 1mb picture it takes really long (1min aprox) to complete ussing only two phones connecting to each other via wifi. Here is my code (sorry for the long code)
SENDER CLASS
public class SenderBroadcastAsyncTask extends AsyncTask<File, Integer, String> {
Context context;
public SenderBroadcastAsyncTask(Context context) {
this.context = context.getApplicationContext();
}
#Override
protected String doInBackground(File... imagen) {
Log.d("SENDER","INICIANDO EL SOCKET PARA ENVIAR");
InetAddress group = null;
try {
group = InetAddress.getByName("192.168.49.255");
} catch (UnknownHostException e) {
e.printStackTrace();
}
int port =1212;
DatagramSocket socket = null;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
try {
socket.setBroadcast(true);
} catch (SocketException e) {
e.printStackTrace();
}
DatagramSocket rsocket = null;
try {
rsocket = new DatagramSocket(1513);
} catch (SocketException e) {
e.printStackTrace();
}
try {
rsocket.setSoTimeout(2000);
} catch (SocketException e) {
e.printStackTrace();
}
for (File i:imagen) {
Bitmap bitmap = BitmapFactory.decodeFile(i.getAbsolutePath());
ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream2);
byte[] prebuf = stream2.toByteArray();
mandar(prebuf, rsocket, socket, group, port);
}
return "ok";
}
public void mandar(byte[] prebuf,DatagramSocket rsocket,DatagramSocket socket,InetAddress group,int port) {
int DATAGRAM_MAX_SIZE = 50*1024;
int cantidadpedazos = (int) Math.ceil(prebuf.length / (float) DATAGRAM_MAX_SIZE);
Log.d("Pedazos", Integer.toString(cantidadpedazos));
//Loop peaces
for (int i = 1; i <= cantidadpedazos; i++) {
enviar(i,socket,group,port,prebuf,DATAGRAM_MAX_SIZE,cantidadpedazos);
}
////FINAL DONE
String message_to_send = "DONE";
byte[] ultimo = message_to_send.getBytes();
DatagramPacket ultimopaquete = new DatagramPacket(ultimo, ultimo.length, group, port);
try {
socket.send(ultimopaquete);
} catch (IOException e) {
e.printStackTrace();
}
/*AFTER DONE WAIT FOR INVERSE ACK OF NUMERED PACKETS*/
boolean mandarfaltan = false;
boolean ack = false;
int countertoend=0;
boolean cancelcheck = false;
while (!ack) {
byte[] recibir = new byte[5];
DatagramPacket pkgrecibir = new DatagramPacket(recibir, 0, recibir.length);
Log.d("UDP", "S: Receiving...");
try {
rsocket.receive(pkgrecibir);
} catch (SocketTimeoutException e) {
Log.d("timeout","TIMEOUT EXCEPTION");
if (mandarfaltan) {
try {
socket.send(ultimopaquete);
} catch (IOException q) {
q.printStackTrace();
}
if (countertoend ==7)
{
Log.d("error","timeout error no response to done");
socket.close();
rsocket.close();
break;
}
cancelcheck = true;
countertoend++;
} else {
Log.d("ACK", "TIMEOUT CANELING PASSING TO DONE");
socket.close();
rsocket.close();
break;
}
} catch (IOException e) {
e.printStackTrace();
}
mandarfaltan = true;
if (!cancelcheck) {
String faltast = new String(pkgrecibir.getData()).trim();
Integer faltaint = Integer.parseInt(faltast); ////euivalent to for i
enviar(faltaint, socket, group, port, prebuf, DATAGRAM_MAX_SIZE, cantidadpedazos);
if (new String(pkgrecibir.getData()).trim().contains("DONE")) {
Log.d("ACK", "Received" + " " + new String(pkgrecibir.getData()).trim());
ack = true;
}
}
cancelcheck = false;
}
}
public void enviar(int i,DatagramSocket socket,InetAddress group,int port,byte[] prebuf,int DATAGRAM_MAX_SIZE,int cantidadpedazos){
//for (int i = 1; i <= cantidadpedazos; i++) {
////EN cada interaccion del for clono el array con las ip q recibiran el paquete
//ArrayList<String> finallist = (ArrayList<String>) tosend.clone();
String final_str = null;
String counter_str = Integer.toString(i);
int len = counter_str.length();
byte[] final_strbyte = new byte[5];
Log.d("HEADER", counter_str + " TAMANO " + Integer.toString(len));
switch (len) {
case 1:
final_str = "0000" + Integer.toString(i);
final_strbyte = final_str.getBytes();
break;
case 2:
final_str = "000" + counter_str;
final_strbyte = final_str.getBytes();
break;
case 3:
final_str = "00" + counter_str;
final_strbyte = final_str.getBytes();
break;
case 4:
final_str = "0" + counter_str;
final_strbyte = final_str.getBytes();
break;
case 5:
final_str = counter_str;
final_strbyte = final_str.getBytes();
break;
}
byte[] slice, imagetosend;
DatagramPacket packet;
if (i == 1) {
slice = Arrays.copyOfRange(prebuf, 0, i * DATAGRAM_MAX_SIZE);
imagetosend = new byte[slice.length + 5];
for (int s = 0; s < 5; s++) {
imagetosend[s] = final_strbyte[s];
}
for (int s = 0; s < slice.length; s++) {
imagetosend[s + 5] = slice[s];
}
packet = new DatagramPacket(imagetosend, imagetosend.length, group, port);
for (int s = 0; s < 1; s++) {
try {
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
} else if (i == cantidadpedazos) {
slice = Arrays.copyOfRange(prebuf, (i - 1) * DATAGRAM_MAX_SIZE, prebuf.length);
imagetosend = new byte[slice.length + 5];
for (int s = 0; s < 5; s++) {
imagetosend[s] = final_strbyte[s];
}
for (int s = 0; s < slice.length; s++) {
imagetosend[s + 5] = slice[s];
}
packet = new DatagramPacket(imagetosend, imagetosend.length, group, port);
for (int s = 0; s < 2; s++) {
try {
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
slice = Arrays.copyOfRange(prebuf, ((i - 1) * DATAGRAM_MAX_SIZE), i * DATAGRAM_MAX_SIZE);
imagetosend = new byte[slice.length + 5];
for (int s = 0; s < 5; s++) {
imagetosend[s] = final_strbyte[s];
}
for (int s = 0; s < slice.length; s++) {
imagetosend[s + 5] = slice[s];
}
packet = new DatagramPacket(imagetosend, imagetosend.length, group, port);
for (int s = 0; s < 2; s++) {
try {
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
RECEIVE CLASS
public class ReceiverBroadcastAsyncTask extends AsyncTask<Void, Integer ,String > {
boolean running = true;
Context context;
//public int counter = 1;
public ReceiverBroadcastAsyncTask(Context context) {
this.context = context.getApplicationContext();
}
#Override
protected String doInBackground(Void... params) {
Log.d("CLASS","INSIDE_MULTICAST RECEIVER");
////receive socket
int port =1212;
DatagramSocket socket = null;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
try {
socket.setBroadcast(true);
} catch (SocketException e) {
e.printStackTrace();
}
//////send socket
int eport = 1513;
InetAddress eip = null;
try {
eip = InetAddress.getByName("192.168.49.1");
} catch (UnknownHostException e) {
e.printStackTrace();
}
DatagramSocket esocket = null;
try {
esocket = new DatagramSocket(eport);
} catch (SocketException e) {
e.printStackTrace();
}
//////end sockets
/////Array used for organize the received packages and log the received headers to send inverse ack
ArrayList<Integer> headers = new ArrayList<Integer>();
ArrayList<byte[]> contenido = new ArrayList<byte[]>();
for (int a=0;a<30000;a++)
{
contenido.add(null);
}
ByteArrayOutputStream imagen = new ByteArrayOutputStream();
int counter = 0;
////////end arrays
//////Start receive
while(true)
{
byte[] message = new byte[60*1024];
DatagramPacket recv_packet = new DatagramPacket(message, message.length);
try {
socket.receive(recv_packet);
} catch (IOException e) {
e.printStackTrace();
}
byte[] order = new byte[5];
Log.d("UDP", "S: Receiving...escuchando en el puerto " + recv_packet.getPort() );
String rec_str;
String rec_order;
Log.d("PACKAGE LENGTH",Integer.toString(recv_packet.getLength()));
if(recv_packet.getLength()>5) ////Packages that are minor to 5 are done packages
{
byte[] buff = new byte[recv_packet.getLength()-5];
System.arraycopy(recv_packet.getData(), 5, buff, 0, buff.length);
System.arraycopy(recv_packet.getData(), 0, order, 0, 5);
rec_str = new String(buff);
rec_order = new String(order);
Log.d("DATA", " " + counter + " " + rec_order);
/////add int counter to array
///////process buff to add to contenido array whit headers as index
if (process(headers,contenido,rec_str,imagen,buff,counter,Integer.parseInt(rec_order),esocket)){
counter =Integer.parseInt(rec_order);}
////end buff processing
}
else ////done package
{
byte[] buff = new byte[recv_packet.getLength()];
System.arraycopy(recv_packet.getData(), 0, buff, 0, buff.length);
rec_str = new String(buff);
counter=0;
///procesar paquetes done o querys..
if (process(headers,contenido,rec_str, imagen, buff, counter, 0,esocket)){
//counter++;
}
}
////end while
}
////end doInBackground
}
/*image processing bound to notification*/
public void procesar( ByteArrayOutputStream imagen) {
Log.d("IMAGEN_PROCESSING", "INSIDE....");
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath();
File file = new File(fullPath, "something" + timeStamp + ".png");
try {
File dir = new File(fullPath);
if (!dir.exists()) {
dir.mkdirs();
}
OutputStream fOut = null;
file.createNewFile();
fOut = new FileOutputStream(file.getPath());
Log.d("File created", file.getAbsolutePath());
fOut.write(imagen.toByteArray());
if(fOut!=null){fOut.close();}
} catch (Exception e) {
}
Bitmap bmp = BitmapFactory.decodeByteArray(imagen.toByteArray(),0,imagen.toByteArray().length);
notification(context,bmp,file);
}
/*end image processing */
/*INVERSE ACK*/
public void inverseack(ArrayList<byte[]> contenido ,ArrayList<Integer> headers,DatagramSocket esocket){
running = false;
Set<Integer> noduplicate = new HashSet<>();
noduplicate.addAll(headers);
headers.clear();
headers.addAll(noduplicate);
Collections.sort(headers);
ArrayList<Integer> faltante= new ArrayList<Integer>();
if (headers.size()!=0)
{
for (int o=1 ; o<=headers.get(headers.size()-1);o++)
{
if(!headers.contains(o)) {
faltante.add(o);
Log.d("Falta"," "+o);
}
}
if (faltante.isEmpty()) {
Log.d("PROCESAR","YA ESTA TODO, listo para procesar imagen");
ByteArrayOutputStream finalbyte = new ByteArrayOutputStream();
for(byte[] w:contenido)
{
if (w!=null) {
finalbyte.write(w, 0, w.length);
}
else break;
}
String message_to_send = "DONE";
byte[] ultimo = message_to_send.getBytes();
InetAddress group = null;
try {
group = InetAddress.getByName("192.168.49.1");
} catch (UnknownHostException e) {
e.printStackTrace();
}
DatagramPacket ultimopaquete = new DatagramPacket(ultimo, ultimo.length, group, 1513);
try {
esocket.send(ultimopaquete);
} catch (IOException e) {
e.printStackTrace();
}
procesar(finalbyte);
headers.clear();
contenido.clear();
/////imagen processing ready ... process
Log.d("PROCESAR","YA ESTA TODO, listo para procesar imagen");
}
else {
for (int enviar : faltante) {
String faltantevalue = Integer.toString(enviar);
byte[] enviarfaltante = new byte[faltantevalue.length()];
enviarfaltante = faltantevalue.getBytes();
InetAddress group = null;
try {
group = InetAddress.getByName("192.168.49.1"); //<-- Wifi direct group server ip address
} catch (UnknownHostException e) {
e.printStackTrace();
}
DatagramPacket ultimopaquete = new DatagramPacket(enviarfaltante, enviarfaltante.length, group, 1513);
try {
esocket.send(ultimopaquete);
} catch (IOException e) {
e.printStackTrace();
}
}
}
faltante.clear();
running=true;
///end for
}///end else
////end inverseack
}
///////Process received packages
public boolean process(ArrayList<Integer> headers,ArrayList<byte[]> contenido,String string,ByteArrayOutputStream total,byte[] buff,int counter,int rec,DatagramSocket esocket)
{
Log.d("rec" + Integer.toString(rec),"counter " + Integer.toString(counter));
if (string.contains("DONE")) {
Log.d("INVERSEACK","SENDING INVERSE ACK");
if (running){ inverseack(contenido,headers,esocket);}
counter = 0;
//return false;
}
else if (rec != counter) {
contenido.set(rec-1,buff);
headers.add(rec);
Log.d("RECIBED", "NEW PACKAGE WILL BE SEND");
return true;
}
else{return false;}
return false;
}
///////////////NOTIFICATION
public void notification(Context context,Bitmap bpm, File imagen) {
Intent pendingintent = new Intent();
pendingintent.setAction(Intent.ACTION_VIEW);
pendingintent.setDataAndType(Uri.fromFile(imagen),"image/*");
PendingIntent intentpending = PendingIntent.getActivity(this.context, 0, pendingintent, 0);
NotificationManager notification = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification noti = new Notification.Builder(context)
.setContentTitle("Photo!")
.setContentText("Photo CLICK to see")
.setSmallIcon(R.drawable.photo)
.setContentIntent(intentpending)
.setLargeIcon(bpm)
.setLights(-256, 100, 100)
.build();
notification.notify(0,noti);
}
#Override
protected void onPostExecute(String result) {
//do whatever...
}
protected void onProgressUpdate(Integer... Progress)
{
}
}
I really appreciate if someone can check and let me know what may be causing that BIG delay on file reception. (it is udp it´s suppose to be quick)
Thanks in advance
The server accept requests from clients but clients don't get an answer from the server, on the server it accepts client authentication but then the client application shows an error message.
The server and client are on the same LAN.
This is the code of server :
public class UdpServer extends BaseServer {
public static final int UDP_BUFFER = 10 * 1024; // 10Kb
private static final int NUMBER_USER_INFO_REQUEST_RETRIES = 5;
private static final int SECONDS_TO_CHECK_USER_INFO = 15;
DatagramSocket inSocket = null;
DatagramSocket outSocket = null;
BlockingQueue<DatagramPacket> incomingRequests = null;
BlockingQueue<DatagramPacket> outgoingRequests = null;
HandleIncomingPackets handleIncomingPackets = null;
HandleRequests handleRequests = null;
HandleOutgoingPackets handleOutgoingPackets = null;
HandleUserInfoUpdates handleUserInfoUpdates = null;
public UdpServer() throws IOException {
this(4445);
}
public UdpServer(int port) throws IOException {
super();
inSocket = new DatagramSocket(port);
outSocket = new DatagramSocket();
try {
serverUserInfo = new UserInfo(UserInfo.SERVER_USERNAME, inSocket.getLocalAddress().getHostAddress(), inSocket.getLocalPort());
} catch (InvalidDataException e) {
if (DEBUG)
System.out.println("oops... initialising serverUserInfo");
}
incomingRequests = new LinkedBlockingQueue<>();
outgoingRequests = new LinkedBlockingQueue<>();
}
public void run() {
handleIncomingPackets = new HandleIncomingPackets();
handleRequests = new HandleRequests();
handleOutgoingPackets = new HandleOutgoingPackets();
handleUserInfoUpdates = new HandleUserInfoUpdates();
handleIncomingPackets.start();
handleRequests.start();
handleOutgoingPackets.start();
handleUserInfoUpdates.start();
System.out.println("Server Started");
}
private class HandleIncomingPackets extends Thread {
private boolean canRun = true;
private byte[] buf;
private DatagramPacket packet;
#Override
public void run() {
while (canRun) {
buf = new byte[UDP_BUFFER];
packet = new DatagramPacket(buf, buf.length);
try {
inSocket.receive(packet);
} catch (IOException e2) {
if (DEBUG)
System.out.println("ops... receiving a packet from socket");
continue;
}
incomingRequests.add(packet);
}
}
public void stopHandleMessages() {
canRun = false;
}
}
private class HandleOutgoingPackets extends Thread {
private boolean canRun = true;
#Override
public void run() {
while (canRun) {
DatagramPacket dp = null;
try {
dp = outgoingRequests.take();
} catch (InterruptedException e1) { }
if (dp == null)
continue;
try {
outSocket.send(dp);
} catch (IOException e) {
if (DEBUG)
System.out.println("could not send a message: " + dp.toString());
}
}
}
public void stopHandleMessages() {
canRun = false;
}
}
private class HandleRequests extends Thread {
private boolean canRun = true;
#Override
public void run() {
while (canRun) {
DatagramPacket dp = null;
try {
dp = incomingRequests.take();
} catch (InterruptedException e1) { }
if (dp == null)
continue;
String the_msg = new String(dp.getData(), 0, dp.getLength());
the_msg = the_msg.trim();
String message_type = null;
try {
message_type = Procedures.getMessageType(the_msg);
} catch (XmlMessageReprException e) {
if (DEBUG)
System.out.println("Cannot get the message type :( " + e.getMessage());
continue;
}
if (message_type == null) {
if (DEBUG)
System.out.println("message type is null");
continue;
}
if (Procedures.isLoginMessage(message_type)) {
manageLoginRequest(dp);
} else if (Procedures.isRegisterMessage(message_type)) {
manageRegisterRequest(dp);
} else if (Procedures.isLogoutMessage(message_type)) {
manageLogoutRequest(dp);
} else if (Procedures.isUserInfoAnswerMessage(message_type)) {
manageUserInfoAnswer(dp);
}
// do stuff
}
}
public void stopHandleMessages() {
canRun = false;
}
}
private class HandleUserInfoUpdates extends Thread {
boolean canRun = true;
#Override
public void run() {
while (canRun) {
Calendar c = Calendar.getInstance();
Date now = c.getTime();
for (SimpleIMUser simu : registeredUsers) {
// now - last >= Seconds to check
// now >= last + seconds to check
if (!simu.getUser().isOnline())
continue;
c.setTime(simu.last_update);
c.add(Calendar.SECOND, SECONDS_TO_CHECK_USER_INFO * NUMBER_USER_INFO_REQUEST_RETRIES);
if (now.after(c.getTime())) {
simu.getUser().setOffline();
if (DEBUG)
System.out.println("HandlerUserInfoUpdates - set "+ simu.getUser() + " offline...");
continue;
}
c.setTime(simu.last_update);
c.add(Calendar.SECOND, SECONDS_TO_CHECK_USER_INFO);
if (now.after(c.getTime())) {
sendUserInfoRequest(simu);
if (DEBUG)
System.out.println("HandlerUserInfoUpdates - send a userInfoRequest... to: " + simu.getUser());
}
}
try {
Thread.sleep(SECONDS_TO_CHECK_USER_INFO * 1000);
} catch (InterruptedException e) { }
}
}
public void stopHandleMessages() {
canRun = false;
}
}
/*
* various requests/messages managers
*
*/
private void sendUserInfoRequest(SimpleIMUser simu) {
UserInfoRequestMessage uirm = new UserInfoRequestMessage(serverUserInfo);
String uirmXml = null;
try {
uirmXml = uirm.toXML();
} catch (ParserConfigurationException | TransformerException e1) {
//unlikely to be here
}
DatagramPacket p;
try {
p = new DatagramPacket(uirmXml.getBytes(), uirmXml.getBytes().length,
InetAddress.getByName(simu.getUser().getIp()),
simu.getUser().getPort());
} catch (UnknownHostException e) {
/* if there's error... nothing to do */
return;
}
outgoingRequests.add(p);
}
private void manageUserInfoAnswer(DatagramPacket dp) {
String msg = new String(dp.getData(), 0, dp.getLength());
UserInfoAnswerMessage uiam;
try {
uiam = UserInfoAnswerMessage.fromXML(msg);
} catch (XmlMessageReprException e) {
//nothing to do...
return;
}
UserInfo source = uiam.getSource();
SimpleIMUser simu = getTheUserFromRegistered(source);
if (simu == null)
return;
simu.getUser().locationData(source.hasLocationData());
simu.getUser().setAltitude(source.getAltitude());
simu.getUser().setLatitude(source.getLatitude());
simu.getUser().setLongitude(source.getLongitude());
simu.getUser().setIP(source.getIp());
simu.getUser().setPort(source.getPort());
simu.getUser().setOnline();
simu.last_update = Calendar.getInstance().getTime();
}
private void manageLogoutRequest(DatagramPacket dp) {
String request = new String(dp.getData(), 0, dp.getLength());
LogoutMessage lm = null;
try {
lm = LogoutMessage.fromXML(request);
} catch (XmlMessageReprException e) {
return;
}
UserInfo source = lm.getSource();
SimpleIMUser s = getTheUserFromRegistered(source);
if (s == null)
return;
s.getUser().setOffline();
s.last_update = Calendar.getInstance().getTime();
}
private void manageLoginRequest(DatagramPacket packet) {
String request = new String(packet.getData(), 0, packet.getLength());
LoginMessage lm = null;
UserInfo userOfMessage = null;
String password = null;
SimpleIMUser s;
String answer = null;
InetAddress address;
int port;
try {
lm = LoginMessage.fromXML(request);
} catch (XmlMessageReprException e1) {
if (DEBUG)
System.out.println("Login message cannot be serialized :(");
}
userOfMessage = lm.getUser();
password = lm.getPassword();
if (DEBUG)
System.out.println("Login message recieved from \"" + userOfMessage.getUsername() +"\"");
s = getTheUserFromRegistered(userOfMessage);
if (s == null || (s != null && !s.samePassword(password))) {
if (DEBUG)
System.out.println("Sending REFUSE login to \"" + userOfMessage.getUsername() +"\"");
try {
answer = new LoginMessageAnswer(userOfMessage).toXML();
} catch (ParserConfigurationException | TransformerException e) {
if (DEBUG)
System.out.println("ops... should not be here :(");
}
address = packet.getAddress();
port = packet.getPort();
outgoingRequests.add(new DatagramPacket(answer.getBytes(), answer.getBytes().length, address, port));
} else {
if (DEBUG)
System.out.println("Sending ACCEPT login to \"" + userOfMessage.getUsername() +"\"");
address = packet.getAddress();
port = packet.getPort();
s.getUser().locationData(userOfMessage.hasLocationData());
s.getUser().setAltitude(userOfMessage.getAltitude());
s.getUser().setLatitude(userOfMessage.getLatitude());
s.getUser().setLongitude(userOfMessage.getLongitude());
s.getUser().setIP(address.getHostAddress());
s.getUser().setPort(port);
s.getUser().setOnline();
s.last_update = Calendar.getInstance().getTime();
try {
answer = new LoginMessageAnswer(s.getUser(), String.valueOf(s.getUser().hashCode())).toXML();
} catch (ParserConfigurationException | TransformerException e) {
if (DEBUG)
System.out.println("ops... making a loginAnswer message");
}
outgoingRequests.add(new DatagramPacket(answer.getBytes(), answer.getBytes().length, address, port));
ListMessage listMessage = new ListMessage();
fillListMessage(listMessage, s);
try {
answer = listMessage.toXML();
} catch (ParserConfigurationException | TransformerException e) { }
outgoingRequests.add(new DatagramPacket(answer.getBytes(), answer.getBytes().length, address, port));
}
}
private void manageRegisterRequest(DatagramPacket dp) {
String request = new String(dp.getData(), 0, dp.getLength());
RegisterMessage rm = null;
String answer = null;
try {
rm = RegisterMessage.fromXML(request);
} catch (XmlMessageReprException e) {
if (DEBUG)
System.out.println("Register message cannot be serialized :(");
}
if (DEBUG)
System.out.println("Register message recieved from \"" + rm.getUser().getUsername() +"\"");
if (registeredUsers.contains(new SimpleIMUser(rm.getUser(), "DUMMY")) || rm.getUser().equals(serverUserInfo)) {
if (DEBUG)
System.out.println("Sending REFUSE register to \"" + rm.getUser().getUsername() +"\"");
try {
answer = new RegisterMessageAnswer(rm.getUser(), RegisterMessageAnswer.REFUSED).toXML();
} catch (ParserConfigurationException | TransformerException e) {
if (DEBUG)
System.out.println("ops... should not be here :(");
} catch (InvalidDataException e) {
if (DEBUG)
System.out.println("ops... should not be here :(");
}
} else {
if (DEBUG)
System.out.println("Sending ACCEPT register to \"" + rm.getUser().getUsername() +"\"");
rm.getUser().setOffline();
addUserToRegisteredUsers(new SimpleIMUser(rm.getUser(), rm.getPassword()));
try {
answer = new RegisterMessageAnswer(rm.getUser(),RegisterMessageAnswer.ACCEPTED).toXML();
} catch (ParserConfigurationException | TransformerException e) {
if (DEBUG)
System.out.println("ops... should not be here :(");
} catch (InvalidDataException e) {
if (DEBUG)
System.out.println("ops... should not be here :(");
}
}
outgoingRequests.add(new DatagramPacket(answer.getBytes(), answer.getBytes().length, dp.getAddress(), dp.getPort()));
}
#Override
protected void finalize() throws Throwable {
handleUserInfoUpdates.stopHandleMessages();
handleRequests.stopHandleMessages();
handleOutgoingPackets.stopHandleMessages();
handleIncomingPackets.stopHandleMessages();
inSocket.close();
outSocket.close();
super.finalize();
}
}
Anything you could do to help or tell me what I am doing wrong is appreciated.
i have written a java code to transfer files from one server to another using the concept of socket programming. now in the same code i also want to check for the network connection availability before each file is transferred. i also want that the files transferred should be transferred according to their numerical sequence. And while the files are being transferred the transfer progress of each file i.e the progress percentage bar should also be visible on the screen.
i will really appreciate if someone can help me with the code. i am posting the code i have written for file transfer.
ClientMain.java
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ClientMain {
private DirectoryTxr transmitter = null;
Socket clientSocket = null;
private boolean connectedStatus = false;
private String ipAddress;
String srcPath = null;
String dstPath = "";
public ClientMain() {
}
public void setIpAddress(String ip) {
this.ipAddress = ip;
}
public void setSrcPath(String path) {
this.srcPath = path;
}
public void setDstPath(String path) {
this.dstPath = path;
}
private void createConnection() {
Runnable connectRunnable = new Runnable() {
public void run() {
while (!connectedStatus) {
try {
clientSocket = new Socket(ipAddress, 3339);
connectedStatus = true;
transmitter = new DirectoryTxr(clientSocket, srcPath, dstPath);
} catch (IOException io) {
io.printStackTrace();
}
}
}
};
Thread connectionThread = new Thread(connectRunnable);
connectionThread.start();
}
public static void main(String[] args) {
ClientMain main = new ClientMain();
main.setIpAddress("10.6.3.92");
main.setSrcPath("E:/temp/movies/");
main.setDstPath("D:/tcp/movies");
main.createConnection();
}
}
(DirectoryTxr.java)
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class DirectoryTxr {
Socket clientSocket = null;
String srcDir = null;
String dstDir = null;
byte[] readBuffer = new byte[1024];
private InputStream inStream = null;
private OutputStream outStream = null;
int state = 0;
final int permissionReqState = 1;
final int initialState = 0;
final int dirHeaderSendState = 2;
final int fileHeaderSendState = 3;
final int fileSendState = 4;
final int fileFinishedState = 5;
private boolean isLive = false;
private int numFiles = 0;
private int filePointer = 0;
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
String dirFailedResponse = "Failed";
File[] opFileList = null;
public DirectoryTxr(Socket clientSocket, String srcDir, String dstDir) {
try {
this.clientSocket = clientSocket;
inStream = clientSocket.getInputStream();
outStream = clientSocket.getOutputStream();
isLive = true;
this.srcDir = srcDir;
this.dstDir = dstDir;
state = initialState;
readResponse(); //starting read thread
sendMessage(request);
state = permissionReqState;
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendMessage(String message) {
try {
sendBytes(request.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* Thread to read response from server
*/
private void readResponse() {
Runnable readRunnable = new Runnable() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
} catch (SocketException se) {
System.exit(0);
} catch (IOException io) {
io.printStackTrace();
isLive = false;
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void sendDirectoryHeader() {
File file = new File(srcDir);
if (file.isDirectory()) {
try {
String[] childFiles = file.list();
numFiles = childFiles.length;
String dirHeader = "$" + dstDir + "#" + numFiles + "&";
sendBytes(dirHeader.getBytes("UTF-8"));
} catch (UnsupportedEncodingException en) {
en.printStackTrace();
}
} else {
System.out.println(srcDir + " is not a valid directory");
}
}
private void sendFile(String dirName) {
File file = new File(dirName);
if (!file.isDirectory()) {
try {
int len = (int) file.length();
int buffSize = len / 8;
//to avoid the heap limitation
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
int numRead = 0;
while (numRead >= 0) {
ByteBuffer buf = ByteBuffer.allocate(1024 * 100000);
numRead = channel.read(buf);
if (numRead > 0) {
byte[] array = new byte[numRead];
System.arraycopy(buf.array(), 0, array, 0, numRead);
sendBytes(array);
}
}
System.out.println("Finished");
} catch (IOException io) {
io.printStackTrace();
}
}
}
private void sendHeader(String fileName) {
try {
File file = new File(fileName);
if (file.isDirectory())
return;//avoiding child directories to avoid confusion
//if want we can sent them recursively
//with proper state transitions
String header = "&" + fileName + "#" + file.length() + "*";
sendHeader(header);
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (clientSocket) {
if (outStream != null) {
try {
outStream.write(dataBytes);
outStream.flush();
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
private void processBytes(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(respServer) && state == permissionReqState) {
state = dirHeaderSendState;
sendDirectoryHeader();
} else if (message.trim().equalsIgnoreCase(dirResponse) && state == dirHeaderSendState) {
state = fileHeaderSendState;
if (LocateDirectory()) {
createAndSendHeader();
} else {
System.out.println("Vacant or invalid directory");
}
} else if (message.trim().equalsIgnoreCase(fileHeaderRecvd) && state == fileHeaderSendState) {
state = fileSendState;
sendFile(opFileList[filePointer].toString());
state = fileFinishedState;
filePointer++;
} else if (message.trim().equalsIgnoreCase(fileReceived) && state == fileFinishedState) {
if (filePointer < numFiles) {
createAndSendHeader();
}
System.out.println("Successfully sent");
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Going to exit....Error ");
// System.exit(0);
} else if (message.trim().equalsIgnoreCase("Thanks")) {
System.out.println("All files were copied");
}
}
private void closeSocket() {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean LocateDirectory() {
boolean status = false;
File file = new File(srcDir);
if (file.isDirectory()) {
opFileList = file.listFiles();
numFiles = opFileList.length;
if (numFiles <= 0) {
System.out.println("No files found");
} else {
status = true;
}
}
return status;
}
private void createAndSendHeader() {
File opFile = opFileList[filePointer];
String header = "&" + opFile.getName() + "#" + opFile.length() + "*";
try {
state = fileHeaderSendState;
sendBytes(header.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
}
}
private void sendListFiles() {
createAndSendHeader();
}
}
(ServerMain.java)
public class ServerMain {
public ServerMain() {
}
public static void main(String[] args) {
DirectoryRcr dirRcr = new DirectoryRcr();
}
}
(DirectoryRcr.java)
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class DirectoryRcr {
String request = "May I send?";
String respServer = "Yes,You can";
String dirResponse = "Directory created...Please send files";
String dirFailedResponse = "Failed";
String fileHeaderRecvd = "File header received ...Send File";
String fileReceived = "File Received";
Socket socket = null;
OutputStream ioStream = null;
InputStream inStream = null;
boolean isLive = false;
int state = 0;
final int initialState = 0;
final int dirHeaderWait = 1;
final int dirWaitState = 2;
final int fileHeaderWaitState = 3;
final int fileContentWaitState = 4;
final int fileReceiveState = 5;
final int fileReceivedState = 6;
final int finalState = 7;
byte[] readBuffer = new byte[1024 * 100000];
long fileSize = 0;
String dir = "";
FileOutputStream foStream = null;
int fileCount = 0;
File dstFile = null;
public DirectoryRcr() {
acceptConnection();
}
private void acceptConnection() {
try {
ServerSocket server = new ServerSocket(3339);
socket = server.accept();
isLive = true;
ioStream = socket.getOutputStream();
inStream = socket.getInputStream();
state = initialState;
startReadThread();
} catch (IOException io) {
io.printStackTrace();
}
}
private void startReadThread() {
Thread readRunnable = new Thread() {
public void run() {
while (isLive) {
try {
int num = inStream.read(readBuffer);
if (num > 0) {
byte[] tempArray = new byte[num];
System.arraycopy(readBuffer, 0, tempArray, 0, num);
processBytes(tempArray);
}
sleep(100);
} catch (SocketException s) {
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException i) {
i.printStackTrace();
}
}
}
};
Thread readThread = new Thread(readRunnable);
readThread.start();
}
private void processBytes(byte[] buff) throws InterruptedException {
if (state == fileReceiveState || state == fileContentWaitState) {
//write to file
if (state == fileContentWaitState)
state = fileReceiveState;
fileSize = fileSize - buff.length;
writeToFile(buff);
if (fileSize == 0) {
state = fileReceivedState;
try {
foStream.close();
} catch (IOException io) {
io.printStackTrace();
}
System.out.println("Received " + dstFile.getName());
sendResponse(fileReceived);
fileCount--;
if (fileCount != 0) {
state = fileHeaderWaitState;
} else {
System.out.println("Finished");
state = finalState;
sendResponse("Thanks");
Thread.sleep(2000);
System.exit(0);
}
System.out.println("Received");
}
} else {
parseToUTF(buff);
}
}
private void parseToUTF(byte[] data) {
try {
String parsedMessage = new String(data, "UTF-8");
System.out.println(parsedMessage);
setResponse(parsedMessage);
} catch (UnsupportedEncodingException u) {
u.printStackTrace();
}
}
private void setResponse(String message) {
if (message.trim().equalsIgnoreCase(request) && state == initialState) {
sendResponse(respServer);
state = dirHeaderWait;
} else if (state == dirHeaderWait) {
if (createDirectory(message)) {
sendResponse(dirResponse);
state = fileHeaderWaitState;
} else {
sendResponse(dirFailedResponse);
System.out.println("Error occurred...Going to exit");
System.exit(0);
}
} else if (state == fileHeaderWaitState) {
createFile(message);
state = fileContentWaitState;
sendResponse(fileHeaderRecvd);
} else if (message.trim().equalsIgnoreCase(dirFailedResponse)) {
System.out.println("Error occurred ....");
System.exit(0);
}
}
private void sendResponse(String resp) {
try {
sendBytes(resp.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private boolean createDirectory(String dirName) {
boolean status = false;
dir = dirName.substring(dirName.indexOf("$") + 1, dirName.indexOf("#"));
fileCount = Integer.parseInt(dirName.substring(dirName.indexOf("#") + 1, dirName.indexOf("&")));
if (new File(dir).mkdir()) {
status = true;
System.out.println("Successfully created directory " + dirName);
} else if (new File(dir).mkdirs()) {
status = true;
System.out.println("Directories were created " + dirName);
} else if (new File(dir).exists()) {
status = true;
System.out.println("Directory exists" + dirName);
} else {
System.out.println("Could not create directory " + dirName);
status = false;
}
return status;
}
private void createFile(String fileName) {
String file = fileName.substring(fileName.indexOf("&") + 1, fileName.indexOf("#"));
String lengthFile = fileName.substring(fileName.indexOf("#") + 1, fileName.indexOf("*"));
fileSize = Integer.parseInt(lengthFile);
dstFile = new File(dir + "/" + file);
try {
foStream = new FileOutputStream(dstFile);
System.out.println("Starting to receive " + dstFile.getName());
} catch (FileNotFoundException fn) {
fn.printStackTrace();
}
}
private void writeToFile(byte[] buff) {
try {
foStream.write(buff);
} catch (IOException io) {
io.printStackTrace();
}
}
private void sendBytes(byte[] dataBytes) {
synchronized (socket) {
if (ioStream != null) {
try {
ioStream.write(dataBytes);
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
}
ClientMain.java and DirectoryTxr.java are the two classes under client application. ServerMain.java and DirectoryRcr.java are the two classes under Server application.
run the ClientMain.java and ServerMain.java
You can sort an array using Arrays.sort(...)
ie
String[] childFiles = file.list();
Arrays.sort(childFiles);
As I understand it, this will sort the files in natural order, based on the file name.
You can modify this by passing a custom Comparator...
Arrays.sort(childFiles, new Comparator<File>() {...}); // Fill out with your requirements...
Progress monitoring will come down to your requirements. Do you want to see only the overall progress of the number of files, the individual files, a combination of both?
What I've done in the past is pre-iterated the file list, calculated the total number of bytes to be copied and used a ProgressMonitor to display the overall bytes been copied...
Otherwise you will need to supply your own dialog. In either case, you will need use SwingUtilities.invokeLater to update them correctly.
Check out Concurrency in Swing for more details.
Network connectivity is subjective. You could simply send a special "message" to there server and wait for a response, but this only suggests that the message was sent and a recipt was received. It could just as easily fail when you start transfering the file again...