i'm new to android and I've been stuck with this for a week now, i did Google a lot
lot and try different things but nothing seem to work for me. I do get something on the client side but i can't open it. here is the server side :
public class MyServer {
Thread m_objThread;
ServerSocket m_server;
String m_strMessage;
DataDisplay m_dataDisplay;
Object m_connected;
public MyServer() {
}
public void setEventListener(DataDisplay dataDisplay) {
m_dataDisplay = dataDisplay;
}
public void startListening() {
m_objThread = new Thread(new Runnable() {
public void run() {
try {
m_server = new ServerSocket(2001);
Socket socket = m_server.accept();
File file = new File("/mnt/extSdCard/pic02.png");
FileInputStream fis = new FileInputStream(file);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
//send an object with data first here
objectOutputStream.flush();
byte[] b = new byte[socket.getSendBufferSize()];
int read = 0;
while ((read = fis.read(b)) != -1) {
objectOutputStream.write(b, 0, read);
}
objectOutputStream.close();
fis.close();
socket.close();
m_server.close();
} catch (Exception e) {
}
}
});
m_objThread.start();
}
}
The client side :
public class ClientActivity extends Activity {
TextView serverMessage;
Thread m_objThreadClient;
Socket socket;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverMessage = (TextView) findViewById(R.id.textView1);
}
public void Start(View view) {
m_objThreadClient = new Thread(new Runnable() {
public void run() {
try {
socket = new Socket("127.0.0.1", 2001);
InputStream reader = socket.getInputStream();
;
FileOutputStream fos = new FileOutputStream(
"/mnt/extSdCard/in04.png");
byte[] b = new byte[socket.getReceiveBufferSize()];
int read = 0;
while ((read = reader.read(b)) != -1) {
fos.write(b, 0, read);
fos.flush();
// / b = new byte[socket.getReceiveBufferSize()];
}
fos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
m_objThreadClient.start();
}
}
You're writing with an ObjectOutputStream but you're not reading with an ObjectInputStream. This does not work. You don't need object streams for this. Just use the streams provided by the socket.
NB Don't flush inside the loop. You don't need to keep reallocating the buffer either.
Related
I am making server-client program, the server is Java on the computer and the client is android app (android studio) and I try to send image from the server to the client, and to show this image on the client's screen by ImageView. The problem is that sometimes its work and sometimes it doesn't work. Looks like there are times that ByteArrayOutputStream.size() return negative value in the client side in the variable len (that keep the length). When the return value is positive it works. Why am I getting negative values (sometimes)?
Server code:
public class Server extends JFrame {
BufferedImage bi,inputImage;
JButton btn;
ServerSocket serverSocket;
Socket socket;
private Scanner in;
private PrintWriter out;
public Server(){
File imageFile = new File("ssss.PNG");
try {
bi = ImageIO.read(imageFile);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
this.add(btn = new JButton("Send"), BorderLayout.NORTH);
this.add(new JLabel(new ImageIcon(bi)), BorderLayout.CENTER);
this.setSize(200, 180);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
try{
serverSocket = new ServerSocket(8000);
socket = serverSocket.accept();
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream(), true);
}
catch(IOException ex){
System.err.println(ex);
}
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
out.println("IMAGE");
sendImage(new File("ssss.PNG"));
// try {
// ImageIO.write(bi, "PNG", socket.getOutputStream());
//} catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
// }
}
});
}
public static void main(String[] args) {
new Server();
}
public void sendImage(File file){
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
DataInputStream dis = new DataInputStream(new FileInputStream(file));
ByteArrayOutputStream ao = new ByteArrayOutputStream();
int read = 0;
byte[] buf = new byte[dis.available()];
while ((read = dis.read(buf)) > -1) {
ao.write(buf, 0, read);
}
System.out.println("ao.size(): "+ao.size());
out.writeInt(ao.size());
out.write(ao.toByteArray());
out.flush();
// out.close();
// dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client code(android):
public class MainActivity extends AppCompatActivity {
public Socket socket;
public PrintWriter out;
public Scanner in;
public TextView textView;
public DataOutputStream dos=null;
public DataInputStream dis=null;
public ImageView imageView;
public Bitmap bitmap;
private static final int SERVERPORT = 8000;
private static final String SERVER_IP = "192.168.5.59";
public static final String TAG="TAG";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.text);
imageView=(ImageView)findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.ic_launcher_background);
new Thread(new ClientThread()).start();
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
Log.d(TAG, "try to connect...");
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream(), true);
Log.d(TAG, "connected1234");
while (in.hasNextLine()) {
String response = in.nextLine();
if (response.startsWith("IMAGE")) {
InputStream in = socket.getInputStream();
Log.d(TAG, "in: "+in);
DataInputStream input = new DataInputStream(in);
Log.d(TAG, "input: "+input);
byte[] data;
int len= input.readInt();
Log.d(TAG, "len: "+len);
data = new byte[len];
Log.d(TAG, "data: "+data);
if (len > 0) {
input.readFully(data,0,data.length);
}
final Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data .length);
Log.d(TAG, "Bitmap: "+bitmap);
runOnUiThread(new Runnable() {
#Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
The error:
len: -298696669
E/AndroidRuntime: FATAL EXCEPTION: Thread-5
Process: com.example.sendimageexample, PID: 17224
java.lang.NegativeArraySizeException: -298696669
at com.example.sendimageexample.MainActivity$ClientThread.run(MainActivity.java:80)
at java.lang.Thread.run(Thread.java:784)`
I solved it!
client code:
public class MainActivity extends AppCompatActivity {
public Socket socket;
public ImageView imageView;
private static final int SERVERPORT = 8000;
private static final String SERVER_IP = "192.168.5.59";
public static final String TAG="TAG";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView=(ImageView)findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.ic_launcher_background);
new Thread(new ClientThread()).start();
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
Log.d(TAG, "try to connect...");
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Log.d(TAG, "Adder: "+serverAddr);
socket = new Socket(serverAddr, SERVERPORT);
InputStream in = socket.getInputStream();
Log.d(TAG, "in: "+in);
DataInputStream input = new DataInputStream(in);
Log.d(TAG, "input: "+input);
Log.d(TAG, "connected1234");
byte[] data;
int len= input.readInt();//-298696669//17976
Log.d(TAG, "len: "+len);
data = new byte[len];
Log.d(TAG, "data: "+data);
if (len > 0) {
input.readFully(data,0,data.length);
}
final Bitmap bitmap = BitmapFactory.decodeByteArray(data , 0, data
.length);
Log.d(TAG, "Bitmap: "+bitmap);
runOnUiThread(new Runnable() {
#Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
ByteArrayOutputStream bos =new ByteArrayOutputStream();
Bitmap bitmap1=BitmapFactory.decodeResource(getResources(),R.drawable.image22);
Log.d(TAG, "bitmap1: "+bitmap1);
bitmap1.compress(Bitmap.CompressFormat.PNG,0,bos);
byte []array=bos.toByteArray();
OutputStream outputStream=socket.getOutputStream();
DataOutputStream dos=new DataOutputStream(outputStream);
dos.writeInt(bos.size());
dos.write(array,0,array.length);
Log.d(TAG, "bos.size: "+bos.size());
Log.d(TAG, "bos.array: "+bos.toByteArray());
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
server code:
public class Server extends JFrame {
BufferedImage bi,inputImage;
JButton btn;
ServerSocket serverSocket;
Socket socket;
private Scanner in;
private PrintWriter out;
Server jframe=this;
public Server(){
File imageFile = new File("ssss.PNG");
try {
bi = ImageIO.read(imageFile);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
this.add(btn = new JButton("Send"), BorderLayout.NORTH);
//this.add(new JLabel(new ImageIcon(bi)), BorderLayout.CENTER);
this.setSize(200, 180);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
try{
serverSocket = new ServerSocket(8000);
socket = serverSocket.accept();
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream(), true);
}
catch(IOException ex){
System.err.println(ex);
}
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
sendImage(new File("ssss.PNG"));
InputStream inputStream;
try {
inputStream = socket.getInputStream();
DataInputStream dis=new DataInputStream(inputStream);
int size = dis.readInt();
System.out.println("size: "+size);
byte[] imageAr = new byte[size];
dis.readFully(imageAr);
System.out.println("imageAr: "+imageAr);
System.out.println("dis: "+dis);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageAr));
jframe.add(new JLabel(new ImageIcon(image)), BorderLayout.CENTER);
revalidate();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// try {
// ImageIO.write(bi, "PNG", socket.getOutputStream());
//} catch (IOException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
// }
}
});
}
public static void main(String[] args) {
new Server();
}
public void sendImage(File file){
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
DataInputStream dis = new DataInputStream(new FileInputStream(file));
ByteArrayOutputStream ao = new ByteArrayOutputStream();
int read = 0;
byte[] buf = new byte[dis.available()];
while ((read = dis.read(buf)) > -1) {
ao.write(buf, 0, read);
System.out.println("read: "+read);
System.out.println("buf: "+buf);
}
System.out.println("ao.size(): "+ao.size());
out.writeInt(ao.size());
System.out.println("ao.toByteArray(): "+ao.toByteArray());
out.write(ao.toByteArray());
out.flush();
// out.close();
// dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I am implementing a socket application where one phone will be a client and the other will be a server. The program is able to send strings using print writer just fine from the client to the sever but when i try to send an image file, it throws an exception. I'd really appreciate if someone could help me out.
Here is the code for the server
public class ServerActivity extends Activity {
private TextView serverStatus;
private ImageView profile;
// DEFAULT IP
public static String SERVERIP = "10.0.2.15";
// DESIGNATE A PORT
public static final int SERVERPORT = 8080;
private Handler handler = new Handler();
private ServerSocket serverSocket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.server);
serverStatus = (TextView) findViewById(R.id.server_status);
profile = (ImageView) findViewById(R.id.image);
String filepath = "/sdcard/DCIM/time table.png";
File imagefile = new File(filepath);
FileInputStream fis = null;
try {
fis = new FileInputStream(imagefile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
profile.setImageBitmap(bm);
SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
//String line;
byte [] line;
Bitmap bitmap;
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// LISTEN FOR INCOMING CLIENTS
Socket client = serverSocket.accept();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Connected.");
}
});
try {
/*InputStream in = client.getInputStream();
line = null;
in.read(line);
Log.d("ServerActivity", line.toString());
bitmap = BitmapFactory.decodeByteArray(line , 0, line.length);*/
int bytesRead;
int current = 0;
int filesize=65383;
byte [] mybytearray2 = new byte [filesize];
InputStream is = client.getInputStream();
FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/IMG-20130112-WA0011.jpeg"); // destination path and name of file
//FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray2,0,mybytearray2.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray2, current, (mybytearray2.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray2, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
//System.out.println(end-start);
bos.close();
handler.post(new Runnable() {
#Override
public void run() {
profile.setImageBitmap(bitmap);
//serverStatus.setText(line);
}
});
/*BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
line = null;
while ((line = in.readLine()) != null) {
Log.d("ServerActivity", line);
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText(line);
// DO WHATEVER YOU WANT TO THE FRONT END
// THIS IS WHERE YOU CAN BE CREATIVE
}
});
}*/
break;
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
// GETS THE IP ADDRESS OF YOUR PHONE'S NETWORK
private String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); }
}
}
} catch (SocketException ex) {
Log.e("ServerActivity", ex.toString());
}
return null;
}
#Override
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And this is the client side code
public class ClientActivity extends Activity {
private EditText serverIp;
private Button connectPhones;
private String serverIpAddress = "";
private boolean connected = false;
private Handler handler = new Handler();
private Socket socket;
private ImageView profile;
private byte [] imgbyte;
String filepath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.client);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
connectPhones.setOnClickListener(connectListener);
profile = (ImageView) findViewById(R.id.imageView1);
filepath = "/sdcard/small.jpg";
File imagefile = new File(filepath);
FileInputStream fis = null;
try {
fis = new FileInputStream(imagefile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
imgbyte = getBytesFromBitmap(bm);
profile.setImageBitmap(bm);
}
private OnClickListener connectListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (!connected) {
serverIpAddress = serverIp.getText().toString();
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
};
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
socket = new Socket(serverAddr, ServerActivity.SERVERPORT);
connected = true;
while (connected) {
try {
/*File myFile = new File (filepath);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = socket.getOutputStream();
Log.d("ClientActivity", "C: Sending command.");
//System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();*/
Log.d("ClientActivity", "C: Sending command.");
/*PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);*/
// WHERE YOU ISSUE THE COMMANDS
OutputStream output = socket.getOutputStream();
Log.d("ClientActivity", "C: image writing.");
output.write(imgbyte);
output.flush();
// out.println("Hey Server!");
Log.d("ClientActivity", "C: Sent.");
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
}
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
socket.close();
connected = false;
} catch (IOException e) {
e.printStackTrace();
}
}
public byte[] getBytesFromBitmap(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 70, stream);
return stream.toByteArray();
}
}
update:
The exception is thrown at the server side code. Its the exception which reads :"Oops. Connection interrupted. Please reconnect your phones."
This is the exception that is thrown:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Thanks everyone , I found the error.
The toast messages have to be inside the UI thread or the handler . As I had a few of them in a non UI thread, it began to throw the exception.
I have created a small server client program for Android. It is working like charm except one thing. First session of file transfer works without any problem, but when I try to send another file, I can't do it without restarting my socket connection. I wanted to achieve this:
1. Start Android server
2. Connect remote client
3. Transfer as many files as one wishes in the same session (without having to restart server and reconnecting client)
How can it be done? Any help would be appreciated!
Here's my code snippet:
Server side methods:
public void initializeServer() {
try {
serverSocket = new ServerSocket(4444);
runOnUiThread( new Runnable() {
#Override
public void run() {
registerLog("Server started successfully at: "+ getLocalIpAddress());
registerLog("Listening on port: 4444");
registerLog("Waiting for client request . . .");
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("Listen failed", "Couldn't listen to port 4444");
}
try {
socket = serverSocket.accept();
runOnUiThread( new Runnable() {
#Override
public void run() {
registerLog("Client connected: "+socket.getInetAddress());
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("Acceptance failed", "Couldn't accept client socket connection");
}
}
Sending file to client:
public void sendFileDOS() throws FileNotFoundException {
runOnUiThread( new Runnable() {
#Override
public void run() {
registerLog("Sending. . . Please wait. . .");
}
});
final long startTime = System.currentTimeMillis();
final File myFile= new File(filePath); //sdcard/DCIM.JPG
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
try {
dis.readFully(mybytearray, 0, mybytearray.length);
OutputStream os = socket.getOutputStream();
//Sending file name and file size to the server
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(myFile.getName());
dos.writeLong(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread( new Runnable() {
#Override
public void run() {
long estimatedTime = (System.currentTimeMillis() - startTime)/1000;
registerLog("File successfully sent");
registerLog("File size: "+myFile.length()/1000+" KBytes");
registerLog("Elapsed time: "+estimatedTime+" sec. (approx)");
registerLog("Server stopped. Please restart for another session.");
}
});
}
Client side (running on PC):
public class myFileClient {
final static String servAdd="10.142.198.127";
static String filename=null;
static Socket socket = null;
static Boolean flag=true;
/**
* #param args
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
initializeClient();
receiveDOS();
}
public static void initializeClient () throws IOException {
InetAddress serverIP=InetAddress.getByName(servAdd);
socket=new Socket(serverIP, 4444);
}
public static void receiveDOS() {
int bytesRead;
InputStream in;
int bufferSize=0;
try {
bufferSize=socket.getReceiveBufferSize();
in=socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
String fileName = clientData.readUTF();
System.out.println(fileName);
OutputStream output = new FileOutputStream("//home//evinish//Documents//Android//Received files//"+ fileName);
long size = clientData.readLong();
byte[] buffer = new byte[bufferSize];
while (size > 0
&& (bytesRead = clientData.read(buffer, 0,
(int) Math.min(buffer.length, size))) != -1) {
output.write(buffer, 0, bytesRead);
size -= bytesRead;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Try flushing just after
output.write(buffer, 0, bytesRead);
If this still doesn't work I found mine server/client works best with objectoutputstreams that you use in the the following way.
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
// always call flush and reset after sending anything
oos.writeObject(server.getPartyMembersNames());
oos.flush();
oos.reset();
YourObject blah = (YourObject) ois.readObject();
I am implementing a socket application where one phone will be a client and the other will be a server. The program is able to send strings using print writer just fine from the client to the sever but when i try to send an image file, it throws an exception. I'd really appreciate if someone could help me out.
Here is the code for the server
public class ServerActivity extends Activity {
private TextView serverStatus;
private ImageView profile;
// DEFAULT IP
public static String SERVERIP = "10.0.2.15";
// DESIGNATE A PORT
public static final int SERVERPORT = 8080;
private Handler handler = new Handler();
private ServerSocket serverSocket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.server);
serverStatus = (TextView) findViewById(R.id.server_status);
profile = (ImageView) findViewById(R.id.image);
String filepath = "/sdcard/DCIM/time table.png";
File imagefile = new File(filepath);
FileInputStream fis = null;
try {
fis = new FileInputStream(imagefile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
profile.setImageBitmap(bm);
SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
//String line;
byte [] line;
Bitmap bitmap;
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// LISTEN FOR INCOMING CLIENTS
Socket client = serverSocket.accept();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Connected.");
}
});
try {
/*InputStream in = client.getInputStream();
line = null;
in.read(line);
Log.d("ServerActivity", line.toString());
bitmap = BitmapFactory.decodeByteArray(line , 0, line.length);*/
int bytesRead;
int current = 0;
int filesize=65383;
byte [] mybytearray2 = new byte [filesize];
InputStream is = client.getInputStream();
FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/IMG-20130112-WA0011.jpeg"); // destination path and name of file
//FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray2,0,mybytearray2.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray2, current, (mybytearray2.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray2, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
//System.out.println(end-start);
bos.close();
handler.post(new Runnable() {
#Override
public void run() {
profile.setImageBitmap(bitmap);
//serverStatus.setText(line);
}
});
/*BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
line = null;
while ((line = in.readLine()) != null) {
Log.d("ServerActivity", line);
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText(line);
// DO WHATEVER YOU WANT TO THE FRONT END
// THIS IS WHERE YOU CAN BE CREATIVE
}
});
}*/
break;
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
// GETS THE IP ADDRESS OF YOUR PHONE'S NETWORK
private String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); }
}
}
} catch (SocketException ex) {
Log.e("ServerActivity", ex.toString());
}
return null;
}
#Override
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And this is the client side code
public class ClientActivity extends Activity {
private EditText serverIp;
private Button connectPhones;
private String serverIpAddress = "";
private boolean connected = false;
private Handler handler = new Handler();
private Socket socket;
private ImageView profile;
private byte [] imgbyte;
String filepath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.client);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
connectPhones.setOnClickListener(connectListener);
profile = (ImageView) findViewById(R.id.imageView1);
filepath = "/sdcard/small.jpg";
File imagefile = new File(filepath);
FileInputStream fis = null;
try {
fis = new FileInputStream(imagefile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
imgbyte = getBytesFromBitmap(bm);
profile.setImageBitmap(bm);
}
private OnClickListener connectListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (!connected) {
serverIpAddress = serverIp.getText().toString();
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
};
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
socket = new Socket(serverAddr, ServerActivity.SERVERPORT);
connected = true;
while (connected) {
try {
/*File myFile = new File (filepath);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = socket.getOutputStream();
Log.d("ClientActivity", "C: Sending command.");
//System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();*/
Log.d("ClientActivity", "C: Sending command.");
/*PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);*/
// WHERE YOU ISSUE THE COMMANDS
OutputStream output = socket.getOutputStream();
Log.d("ClientActivity", "C: image writing.");
output.write(imgbyte);
output.flush();
// out.println("Hey Server!");
Log.d("ClientActivity", "C: Sent.");
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
}
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
socket.close();
connected = false;
} catch (IOException e) {
e.printStackTrace();
}
}
public byte[] getBytesFromBitmap(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 70, stream);
return stream.toByteArray();
}
}
update:
The exception is thrown at the server side code. Its the exception which reads :"Oops. Connection interrupted. Please reconnect your phones."
This is the exception that is thrown:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Thanks everyone , I found the error.
The toast messages have to be inside the UI thread or the handler . As I had a few of them in a non UI thread, it began to throw the exception.
i want to make an application for transfer files using wifi direct, but my send and receiver progress bar won't update
my sender
public void Server () {
new Thread(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
//receive ip
serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
ClientIP = line;
}
in.close();
socket.close();
serverSocket.close();
socket = null;
serverSocket = null;
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//send file
socket = new Socket();
socket.bind(null);
socketAddress = new InetSocketAddress(ClientIP, portal);
socket.connect(socketAddress, SOCKET_TIMEOUT);
FragmentManager fm = getFragmentManager();
md = new MyDialog("Send to " + ClientIP );
md.setRetainInstance(true);
md.setCancelable(true);
md.show(fm, "Sender");
//reset progress bar status
progressBarStatus = 0;
//reset filesize
fileSize = 0;
byte buf[] = new byte[1024];
File myFile = new File (path);
filelength = file.length();
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
while ((len = bis.read(buf)) != -1) {
fileSize+=len;
os.write(buf, 0, len);
os.flush();
//count for progress bar
double d = (double) (fileSize * 100) / filelength;
progressBarStatus = (int) Math.round(d);
progressBarHandler.post(new Runnable() {
public void run() {
md.updateProgress(progressBarStatus);
}
});
}
os.close();
fis.close();
bis.close();
socket.close();
// ok, file is downloaded,
if (progressBarStatus >= 100) {
// sleep 2 seconds, so that you can see the 100%
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
isSent = true;
runOnUiThread(new Runnable() {
public void run() {
if(isSent) {
Toast.makeText(getApplicationContext(), "File Sent", Toast.LENGTH_SHORT).show();
}
}
});
md.dismiss();
}
} catch (IOException e) {
Log.e(TAG, "I/O Exception", e);
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
}
}).start();
}
my receiver
public void Client (final String hostAddress) {
socketAddress = new InetSocketAddress(hostAddress, port);
socket = new Socket();
new Thread(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
//sent ip
socket.bind(null);
socket.connect(socketAddress, SOCKET_TIMEOUT);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(messsage);
out.flush();
out.close();
socket.close();
socket = null;
//receive file
socket = new Socket();
serverSocket = new ServerSocket(portal);
socket = serverSocket.accept();
final String name;
final String ext;
String[] tokens = filename.split("\\.(?=[^\\.]+$)");
name = tokens[0];
ext = tokens[1];
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ getPackageName() + "/" + name + System.currentTimeMillis()
+ "." + ext);
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
FragmentManager fm = getFragmentManager();
md = new MyDialog("Receive from " + HostIP);
md.setRetainInstance(true);
md.setCancelable(true);
md.show(fm, "Receiver");
//reset progress bar status
progressBarStatus = 0;
//reset filesize
fileSize = 0;
filelength = f.length();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[1024];
while ((len = is.read(buf)) != -1) {
bos.write(buf, 0, len);
bos.flush();
fileSize+=len;
double d = (double) (fileSize * 100) / filelength;
progressBarStatus = (int) Math.round(d);
progressBarHandler.post(new Runnable() {
public void run() {
md.updateProgress(progressBarStatus);
}
});
}
is.close();
fos.close();
bos.close();
socket.close();
serverSocket.close();
if (progressBarStatus >= 100) {
// sleep 2 seconds, so that you can see the 100%
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
isSent = true;
// close the progress bar dialog
//progressBar.dismiss();
runOnUiThread(new Runnable() {
public void run() {
// some code #3 (that needs to be ran in UI thread)
if(isSent) {
Toast.makeText(getApplicationContext(), "File Received", Toast.LENGTH_SHORT).show();
btn.setEnabled(true);
}
}
});
md.dismiss();
}
} catch (IOException e) {
Log.e(TAG, "IO Exception.", e);
}
}
}).start();
}
and i use dialog fragment because i use API 14+
my dialog class
public class MyDialog extends DialogFragment {
ProgressBar mProgressBar;
String title;
public MyDialog (String title) {
this.title = title;
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.popup, container);
mProgressBar = (ProgressBar)view.findViewById(R.id.pb);
getDialog().setTitle(title);
getDialog().setCanceledOnTouchOutside(false);
return view;
}
#Override
public void onDestroyView()
{
if (getDialog() != null && getRetainInstance())
getDialog().setDismissMessage(null);
super.onDestroyView();
}
#Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
super.onCancel(dialog);
Toast.makeText(getActivity().getApplicationContext(), "Connection lost. Retry", Toast.LENGTH_SHORT).show();
getActivity().finish();
}
public void updateProgress(int percent)
{
mProgressBar.setProgress(percent);
}
}
i don't know why my code isn't working, my progress bar won't update and file not send.
Anyone can help me? thx before
You've got a lot of code, but as long as I know, the receiver should use an AsyncTask, that's how I do it and it works for me. Instead of a thread use an Asynctask and the OnProgressUpdate method of the AsyncTask to update the ProgressDialog in the main thread.
For example:
public class getFile extends AsyncTask<Void, String, Void>
{
ProgressDialog pB;
String hostAddress=null;
InetSocketAddress socketAddress;
Socket socket=null;
ServerSocket serverSocket=null;
int port=3001;
int SOCKET_TIMEOUT = 3000;
public getFile(String _hostAddress, Context context)
{
this.pB = new ProgressDialog(context);
this.pB.setTitle(context.getText(R.string.sYourMessageText);
this.pB.setMessage(null);
this.pB.setProgressNumberFormat(null);
this.pB.setProgressPercentFormat(null);
this.pB.setCancelable(false);
Drawable d = getResources().getDrawable(R.drawable.x_greenprogress);
pB.setProgressDrawable(d);
pB.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
hostAddress=_hostAddress;
}
#Override
protected void onPreExecute()
{
this.pB.show();
}
#Override
protected Void doInBackground(Void... params)
{
try {
//sent ip
socketAddress = new InetSocketAddress(this.hostAddress, port);
socket = new Socket();
socket.bind(null);
socket.connect(socketAddress, SOCKET_TIMEOUT);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(messsage);
out.flush();
out.close();
socket.close();
socket = null;
//receive file
socket = new Socket();
serverSocket = new ServerSocket(portal);
socket = serverSocket.accept();
final String name;
final String ext;
String[] tokens = filename.split("\\.(?=[^\\.]+$)");
name = tokens[0];
ext = tokens[1];
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ getPackageName() + "/" + name + System.currentTimeMillis()
+ "." + ext);
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[1024];
while ((len = is.read(buf)) != -1)
{
bos.write(buf, 0, len);
bos.flush();
fileSize+=len;
// to update the progress bar just call:
this.publishProgress("" + (int) ((fileSize * 100) / filelength));
}
is.close();
fos.close();
bos.close();
socket.close();
serverSocket.close();
}
#Override
protected void onProgressUpdate(String... progress)
{
this.pB.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(Void result)
{
if (this.pB.isShowing())
this.pB.dismiss();
}
}
EDIT:
By the way, why do you connect to the server, send an IP close the connection and wait for the server to connect? Why don't use the first socket to do the file transfer? The connection has already been established.