简体   繁体   中英

AVD on Windows7 Not able to connect to Linux Server

This pertains to my earlier post "http://stackoverflow.com/questions/8788825/linux-udp-server-unreachable-from-window-7", which has been solved. Now I am moving to my original job of connecting AVD to Linux server.

I am using the following code for connecting to the server

import java.net.*;

class UDPClient {

public final static int DesitnationPort = 9999;
private int mCounter;
private DatagramSocket mClientSocket;
private InetAddress mServerIPAddress;
private byte[] mDataBuffer;
private DatagramPacket mSendPacket;
private DatagramPacket mReceivePacket;

//Constructor
public UDPClient() {

    //Time to make the private data good one
    mCounter =1;
    try {
    mServerIPAddress = InetAddress.getByName("192.168.2.2");
    }
    catch(UnknownHostException e)
    {
        System.out.println("Host cannot be resolved :( ");
    }
    System.out.println("Host has been resolved The IP is valid one ");
    try {
    mClientSocket = new DatagramSocket();
    }
    catch(SocketException e)
    {
        System.out.println("Socket could not be created :( ==> " + e.getMessage());
    }
    System.out.println("Socket has been created ");
    String temp = "This is from the Client == To my Dear Sever :) counter = " + mCounter;
    mDataBuffer = temp.getBytes();
    mSendPacket = new DatagramPacket(mDataBuffer, mDataBuffer.length, mServerIPAddress, DesitnationPort);
    System.out.println("Datagram has been made now ");
    System.out.println("Data ==>"+ mSendPacket.getData());
    System.out.println("Data ==>"+ mSendPacket.getPort());
    System.out.println("Data ==>"+ mSendPacket.getSocketAddress());
    System.out.println("Data ==>"+ mSendPacket.getLength());
}

public void SendDataToServer(){

    try {
            if(!mClientSocket.isClosed())   {

                String temp = "This is from the Client == To my Dear Sever :) counter = " + mCounter;
                mDataBuffer = temp.getBytes();
                mSendPacket = new DatagramPacket(mDataBuffer, mDataBuffer.length, mServerIPAddress, DesitnationPort);           
                mClientSocket.send(mSendPacket);
                System.out.println("Send the packet");
                mCounter++;
            }
            else    {

                System.out.println("Socket is closed");
            }
    }
    catch(Exception e)
    {
        System.out.println("Could not send the data :( ==> " + e.getMessage());
    }
}

public void ReceiveDataFromServer() {

    byte[] tembuff = new byte[1024];
    mReceivePacket = new DatagramPacket(tembuff, tembuff.length);
    try {
            if(!mClientSocket.isClosed())   {

                mClientSocket.receive(mReceivePacket);

            }
            else    {

                System.out.println("Socket is closed");
            }
    }
    catch(Exception e)
    {
        System.out.println("Could not Receive the data :( ");
        return;
    }
        String data = new String(mReceivePacket.getData());
        System.out.println(" Received the Data => " + data);
}
}

This code works well when I simply use the class in java program like this :-

class TryingWithClient {
public static void main(String a[]) {
    UDPClient mClient = new UDPClient();
    while(true) {
    System.out.println("While Starting");
    mClient.SendDataToServer();
    mClient.ReceiveDataFromServer();
    }
 }
}

When I use the same code in AVD project I get a Null pointer exception at the following line :-

public void SendDataToServer(){     
    try {
        if(!mClientSocket.isClosed()){ //<==@ this call Null exception occurs

After browsing internet & android development sites I came to conclusion that I am missing the GMS / GPS functionality which I added to my AVD. Still I am unable to get any clue about this.

Here is my code which calls the above UDPClient.

public class StreamingProjectActivity extends Activity {
/** Called when the activity is first created. */

//All buttons
//private static final String LOG_TAG = "StreamingTest";    
private StreamButton mStreamButton = null;
private UDPClient mClient= null;

class StreamButton extends Button {
    boolean mStartStreaming = true;

    OnClickListener clicker = new OnClickListener() {
        public void onClick(View v) {
            onStream(mStartStreaming);
            if (mStartStreaming) {
                setText("Stop Streaming");
            } else {
                setText("Start recording");
            }
            mStartStreaming = !mStartStreaming;
        }
    };

    public StreamButton(Context ctx) {
        super(ctx);
        setText("Start Streaming");
        setOnClickListener(clicker);
    }
}//class StreamButton Ends

@Override
public void onCreate(Bundle icicle) {
    try {

        mClient = new UDPClient();
        System.out.println("==========> Client created sucessfully :) <====== ");

        super.onCreate(icicle);

        LinearLayout ll = new LinearLayout(this);
        mStreamButton  = new StreamButton(this);
        ll.addView(mStreamButton,
        new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT,
            0));

        setContentView(ll);
        System.out.println("Trying Step 2 now ");
}
catch(Exception e)
{
    System.out.println("Activity could not be launched :( ");   
}

}

//public StreamingTest()
public StreamingProjectActivity(){
System.out.println("Constructor ====>");
System.out.println("Constructor <====");
}//Constructor

private void onStream(boolean start) {
    if (start)
    {
        mClient.SendDataToServer();
        mClient.ReceiveDataFromServer();
        try
          {
            Thread.sleep(4000);  

          }catch (InterruptedException ie)
          {
              System.out.println(ie.getMessage());
          }

    }
 }//onStream
}

Kindly help.

Ok, first of all: never ever print a catched exception with System.out.println("some msg " + e.getMessage()); Please use Log.e(TAG, "my message", e); for that. So you will actually see a stack trace.

Second: I bet that this code throws an error (check if you see the print in your LogCat output):

try {
    mClientSocket = new DatagramSocket();
} catch(SocketException e) {
    System.out.println("Socket could not be created :( ==> " + e.getMessage());
}

That is the only reason that mClientSocket still might be null. As this call might go wrong, you should consider checking for null before you check if the socket is closed.

The problem in my earlier solution was that I was mixing the GUI & network operations in the same thread which is called "StricMode.ThreadPolicy" (although, my problem is only part of what is mentioned in the jargon).

I was getting these exceptions "android.os.NetworkOnMainThreadException & android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099) " which I could make out only after I applied WarrenFaith's suggestion (Thanks Warren).

These are thrown only on violation of "StricMode".

Solution : Simply separate the UI work from the network. I had to write the following code for this :

enum ClientThreadStates {
eUndefined,
eStopped,
eRunning,
eIdle,
eSendToServer,
eReadFromServer
}

public class ClientThread extends Thread {

private UDPClient mClient= null;
private ClientThreadStates mStateOfTheThread = ClientThreadStates.eUndefined;
private static String mLOG_TAG; 

public ClientThread(String s){

    mLOG_TAG = s;
    mStateOfTheThread = ClientThreadStates.eStopped;
    mClient = new UDPClient(s);
    start();
}//constructor

public void SetState(ClientThreadStates paramState) {

    mStateOfTheThread = paramState;
}

public ClientThreadStates GetState() {

    return mStateOfTheThread;
}
private void Action(ClientThreadStates s) {

    synchronized(s) {

        switch(mStateOfTheThread)   {

        case eRunning: //fall
        case eIdle: break;
        case eSendToServer: mClient.SendDataToServer(); break;
        case eReadFromServer: mClient.ReceiveDataFromServer(); break;

        }
        try {
            mStateOfTheThread.wait();
        }
        catch( InterruptedException e ){
            Log.e(mLOG_TAG, "Got Exception at wait <==", e);
        }           

    }
}

public void run() {
    mStateOfTheThread = ClientThreadStates.eRunning;
    System.out.println("In Thread.run .. The State is " + mStateOfTheThread);
    while(ClientThreadStates.eStopped.compareTo(mStateOfTheThread) < 0){ //state >stopped

        Action(mStateOfTheThread);
    }//while

}//run
}//class ClientThread

Finally synchronize on the two threads on the state like this :

private void onStream(boolean start) {

    ClientThreadStates State = mClientThread.GetState();
    synchronized(State) {
        if (start)  {
            mClientThread.SetState(ClientThreadStates.eSendToServer);
        }
        else        {
            mClientThread.SetState(ClientThreadStates.eReadFromServer);
        }
        try {               
            State.notify();
        }
        catch( IllegalMonitorStateException  e ) {
                Log.e(LOG_TAG, "Got Exception @ notify <==", e);
        }        
    }
 }//onStream

}//StreamingProjectActivity

Now the code runs perfectly.

Thanks. Ashutosh

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM