8

I have a client on Android and server on c#. The client sends messages to server and it's fine. But I need server to send on request list of folders and files in specified directory and don't know how to do that, because client doesn't get any messages from server. The client's part of code that is intended to listen doesn't work, the application simply stucks until I close the server application, then it works again, but still doesn't read anything. Thanks in advance

Client:

package com.app.client.app;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStream;
import java.io.OutputStreamWriter; 
import java.io.InputStreamReader;
import java.io.PrintWriter; 
import java.net.InetAddress; 
import java.net.Socket; 
import java.net.UnknownHostException; 

import android.util.Log; 

public class my_activity extends Activity { 
private TextView txt;

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    Button b = (Button)findViewById(R.id.button1);
    txt = (TextView)findViewById(R.id.textView1);


    b.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
        connectSocket("Hello");

        }
    });
} 

private void connectSocket(String a){ 

    try { 
        InetAddress serverAddr = InetAddress.getByName("192.168.1.2"); 
        Log.d("TCP", "C: Connecting..."); 
        Socket socket = new Socket(serverAddr, 4444); 

        message = "1";

        PrintWriter out = null;
        BufferedReader in = null;

        try { 
            Log.d("TCP", "C: Sending: '" + message + "'"); 
            out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true); 
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));                

            out.println(message);
            while ((in.readLine()) != null) {
                txt.append(in.readLine());
            }

            Log.d("TCP", "C: Sent."); 
            Log.d("TCP", "C: Done.");               

        } catch(Exception e) { 
            Log.e("TCP", "S: Error", e); 
        } finally { 
            socket.close(); 
        } 

    } catch (UnknownHostException e) { 
        // TODO Auto-generated catch block 
        Log.e("TCP", "C: UnknownHostException", e); 
        e.printStackTrace(); 
    } catch (IOException e) { 
        // TODO Auto-generated catch block 
        Log.e("TCP", "C: IOException", e); 
        e.printStackTrace(); 
    }       
} 
} 

Server:

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;

public class serv {
    public static void Main() {
    try {
    IPAddress ipAd = IPAddress.Parse("192.168.1.2");
     // use local m/c IP address, and 

     // use the same in the client


/* Initializes the Listener */
    TcpListener myList=new TcpListener(ipAd,4444);

/* Start Listeneting at the specified port */        
    myList.Start();

    Console.WriteLine("The server is running at port 4444...");    
    Console.WriteLine("The local End point is  :" + 
                      myList.LocalEndpoint );
    Console.WriteLine("Waiting for a connection.....");
    m:
    Socket s=myList.AcceptSocket();
    Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);

    byte[] b=new byte[100];
    int k=s.Receive(b);

    char cc = ' ';
    string test = null;
    Console.WriteLine("Recieved...");
    for (int i = 0; i < k-1; i++)
    {
        Console.Write(Convert.ToChar(b[i]));
        cc = Convert.ToChar(b[i]);
        test += cc.ToString();
    }

    switch (test)
    {
        case "1":                 
            break;


    }

    ASCIIEncoding asen=new ASCIIEncoding();
    s.Send(asen.GetBytes("The string was recieved by the server."));
    Console.WriteLine("\nSent Acknowledgement");


/* clean up */
    goto m;    
    s.Close();
    myList.Stop();
    Console.ReadLine();

}
catch (Exception e) {
    Console.WriteLine("Error..... " + e.StackTrace);
}    
}

}
3Gee
  • 1,094
  • 2
  • 14
  • 23
  • Does `Console.WriteLine("Recieved...");` get printed? – Haphazard Jun 17 '11 at 14:55
  • 1
    Just curious why you didnt choose to go with a SOAP approach, performance? – Allen Rice Jun 17 '11 at 14:58
  • I wrote the exact same app (c# server sending file listings to android). I have the source but I stopped working on it a while ago. When I return home from work I'll post it for you (if you haven't found the answer by then and mine still works). – dymmeh Jun 17 '11 at 15:07
  • @Allen I didn't think of SOAP, just found some tutorials and followed them – 3Gee Jun 17 '11 at 16:18
  • @dymmeh That would be great, thanks, looking forward to it! – 3Gee Jun 17 '11 at 16:19
  • @3Gee Do `Log.d("TCP", "C: Sent.");` and `Console.WriteLine("\nSent Acknowledgement");` get sent? Where does it stop writing? – Haphazard Jun 17 '11 at 16:25
  • @Haphazard I think Console.WriteLine("\nSent Acknowledgement"); is not supposed to get sent at all, as well as Log.d("TCP", "C: Sent.");. I tap a button on phone screen and it stucks in state "pressed" until I close the server app. – 3Gee Jun 17 '11 at 17:02
  • @dymmeh Could you please post your app that you mentioned? I would be very grateful. – 3Gee Jun 17 '11 at 21:21
  • Sure! Gimme a bit. I just got home and I want to run through my code and make sure it works properly still – dymmeh Jun 17 '11 at 23:35

3 Answers3

6

Ok, I found the solution to your problem.

In your c# server where you send the text:

ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("The string was recieved by the server."));
s.Close();

Make sure to close the socket here once you send the data. thats why your app would hang. IT was waiting for more input from the server

Also, change to this in Java where you receive

String text = "";
String finalText = "";
while ((text = in.readLine()) != null) {
    finalText += text;
    }
txt.setText(finalText);

Notice how you're doing 2 readInputs in that loop. The while statement does one.. and setting the text does one.. so you're essentially trying to read 2 lines during one loop. Changing to what i posted above will fix that

dymmeh
  • 22,247
  • 5
  • 53
  • 60
  • I've copied and pasted your code into a project and copy and pasted exactly what I have into them and they work perfect every time. – dymmeh Jun 18 '11 at 00:23
  • text += URLDecoder.decode(input, "UTF-8"); <--this line works better than just "finalText += text;" because the result text of the last has "+" signs instead of spaces – 3Gee Jun 18 '11 at 00:41
  • @dymmeh Could you please tell me why you've changed the lines mentioned in previous comment, because I really don't get it – 3Gee Jun 18 '11 at 01:38
  • I put those in there initially because that's how I was doing it in my app. however, I then tested it without and found it wasn't needed to work. I figured adding extra code in there wouldn't help so I removed it. sorry if I confused you! – dymmeh Jun 18 '11 at 03:45
4

To avoid NetworkOnMainThreadException you need to execute the communication code in a new thread.

In the Android client:

 @Override
 public void onClick(View v) {

 new Thread(new Runnable() {
        public void run() {
            connectSocket("Hello");
                }
        }).start();

 }
Natan Braslavski
  • 819
  • 8
  • 18
3

Thank you for you code example!

Just for info:

you need the following permission being set:

    <uses-permission android:name="android.permission.INTERNET" />
Arthur
  • 31
  • 1