简体   繁体   中英

Android TCP Server Client Communication

I found a well written tutorial here for server client communication on android. Works like a charm. But it is only one way communication. I am trying to listen server response in client but not know where I am wrong here. Here is the code for server where I am trying to make changes.

Server

public class Server extends Activity {

    private ServerSocket serverSocket;

    Handler updateConversationHandler;

    Thread serverThread = null;

    private TextView text;



    public static final int SERVERPORT = 8080;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        text = (TextView) findViewById(R.id.text2);

        updateConversationHandler = new Handler();

        this.serverThread = new Thread(new ServerThread());
        this.serverThread.start();

    }

    @Override
    protected void onStop() {
        super.onStop();
        try {
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class ServerThread implements Runnable {

        public void run() {
            Socket socket = null;
            try {
                serverSocket = new ServerSocket(SERVERPORT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            while (!Thread.currentThread().isInterrupted()) {

                try {

                    socket = serverSocket.accept();

                    CommunicationThread commThread = new CommunicationThread(socket);
                    new Thread(commThread).start();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class CommunicationThread implements Runnable {

        private Socket clientSocket;

        private BufferedReader input;

        public CommunicationThread(Socket clientSocket) {

            this.clientSocket = clientSocket;

            try {

                this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void run() {


            while (!Thread.currentThread().isInterrupted()) {

                try {

                    String read = input.readLine();

                     if (read == null ){
                         Thread.currentThread().interrupt();
                     }else{
                         BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
                         out.write("TstMsg");
                         updateConversationHandler.post(new updateUIThread(read));

                     }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    class updateUIThread implements Runnable {
        private String msg;

        public updateUIThread(String str) {
            this.msg = str;
        }

        @Override
        public void run() {
            text.setText("Client Says: "+ msg + new Date() + "\n");

        }

    }

}

Client

public class Client extends Activity {

    private Socket socket;

    private static final int SERVERPORT = 8080;
    private static final String SERVER_IP = "192.168.104.107";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);      
                    new Thread(new ClientThread()).start();

    }


    public void onClick(View view) {
        try {
            EditText et = (EditText) findViewById(R.id.EditText01);
            String str = et.getText().toString();
            PrintWriter out = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream())),
                    true);
            out.println(str);
            out.flush();
            BufferedReader  in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String read = in.readLine();
            System.out.println("MSG:" + read);  

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class ClientThread implements Runnable {

        @Override
        public void run() {

            try {
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
                socket = new Socket(serverAddr, SERVERPORT);

            } catch (UnknownHostException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }

        }

    }
}

Update

When client send any message to server the message is received by server but when server send its response

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
 out.write("TstMsg");

and in client

String read = in.readLine();
System.out.println("MSG:" + read); 

It dose not recieved by client or we can say server listen clients message but client not. I have added both permissions in manifest.

<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>

Update After a long hang comes these errors.

11-28 18:35:45.786: E/GTalkService(292): connectionClosed: no XMPPConnection - That's strange!
11-28 18:35:48.806: D/ConnectivityService(148): handleInetConditionHoldEnd: net=1, condition=0, published condition=0
11-28 18:35:54.526: I/GTalkService/c(292): [AndroidEndpoint@1090563472] connect: acct=1000000, state=CONNECTING
11-28 18:35:55.176: D/dalvikvm(1167): GC_CONCURRENT freed 495K, 9% free 6604K/7239K, paused 2ms+3ms
11-28 18:35:55.226: D/Finsky(1167): [1] 5.onFinished: Installation state replication succeeded.
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349): Problem with socket or streams.
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349): java.net.ConnectException: failed to connect to www.google-analytics.com/173.194.39.41 (port 80): connect failed: ETIMEDOUT (Connection timed out)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at libcore.io.IoBridge.connect(IoBridge.java:114)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at java.net.Socket.connect(Socket.java:842)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at com.google.android.apps.analytics.t.run(Unknown Source)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at android.os.Handler.handleCallback(Handler.java:605)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at android.os.Handler.dispatchMessage(Handler.java:92)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at android.os.Looper.loop(Looper.java:137)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at android.os.HandlerThread.run(HandlerThread.java:60)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349): Caused by: libcore.io.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at libcore.io.Posix.connect(Native Method)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  at libcore.io.IoBridge.connect(IoBridge.java:112)
11-28 18:37:18.276: W/GoogleAnalyticsTracker(349):  ... 9 more
11-28 18:37:29.016: D/dalvikvm(349): GC_CONCURRENT freed 1258K, 35% free 8238K/12487K, paused 2ms+8ms

I am still not to sure about what you are trying to achieve. Your error -log shows a XMPPConnection - Error. XMPP isn't handled over the port you are using in the posted code, so this error message could be either from a different part of your application. The other error message is related to an HTTP - Connection for Google analytics and neither is related to the code snippet that you posted. You should downtrace your problem by: catching possible exceptions, Log.d with a tag you can filter your error - messages by. The hint from Martin James is good I think, so trying to switch to a byte - wise reading of your inputstream at least for verification and downtracing if you receive any data from your server - connection is also a good idea.

readLine() expects an actual line :' A line is considered to be terminated by any one of a line feed ('\\n'), a carriage return ('\\r'), or a carriage return followed immediately by a linefeed.'

You should therefore send one, eg. with BufferedWriter.newLine().

Have you written the following snippet in your code

out.flush();

after

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
out.write("TstMsg");

Have you tried adding a new line ( "\\n" ) when trying to write? Try out.write("TstMsg"+ "\\n") instead.

final Socket s = new Socket();
s.connect(new InetSocketAddress(mHost, mPort), 20000);
final DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.write(("This is a message." + "\r\n").getBytes());
dos.flush();

Alternatively:

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String outgoingMsg = "This is a message." + System.getProperty("line.separator");
out.write(outgoingMsg);
out.flush();

If you are trying to connect to a web server. As far as I know web server handles http protocol and you are trying to connect to a webserver simply with tcp/ip using socket. You will not get expected response as you are violating protocol standard. your option would be if you want to connect to a web server either you use android HttpURLConnection related classes or you create your own application server using severSocket related classes in any programming language to handle your clients.

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