2014年12月16日 星期二

Android-Socket Server 端 接收 訊息

在上一篇有談到 Socket Client 端
以現實中的例子
如果有投手(Client)投球,那就會有捕手(Server)接球
Service以下的例子為例,是不斷地等待相關的訊息

如果有收到相關的訊息,那就會顯示在畫面上

Main.java

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import android.app.Activity;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;

public class MainActivity extends Activity {

    TextView test;
    TextView test2;

    private Handler handler = new Handler();
    private ServerSocket serverSocket;
    private String line ;



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        test = (TextView) findViewById(R.id.text1);
        test2 = (TextView) findViewById(R.id.text2);

        //建立Thread
        Thread fst = new Thread(socket_server);
        //啟動Thread
        fst.start();

    }

    //取得IP
    private String getMyIp(){
        //新增一個WifiManager物件並取得WIFI_SERVICE
        WifiManager wifi_service = (WifiManager)getSystemService(WIFI_SERVICE);
        //取得wifi資訊
        WifiInfo wifiInfo = wifi_service.getConnectionInfo();
        //取得IP,但這會是一個詭異的數字,還要再自己換算才行
        int ipAddress = wifiInfo.getIpAddress();
        //利用位移運算和AND運算計算IP
        String ip = String.format("%d.%d.%d.%d",(ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));
        return ip;
    }


    private Runnable socket_server = new Runnable(){
        public void run(){
            handler.post(new Runnable() {
                public void run() {
                    test.setText("Listening...." + getMyIp());
                }
            });

            try{
                //建立serverSocket
                serverSocket = new ServerSocket(1234);

                //等待連線
                while (true) {
                    //接收連線
                    Socket client = serverSocket.accept();

                    handler.post(new Runnable() {
                        public void run() {
                            test.setText("Connected.");
                        }
                    });
                    try {
                        //接收資料
                        DataInputStream in = new DataInputStream(client.getInputStream());
                        line = in.readUTF();
                        while (line != null) {
                            handler.post(new Runnable() {
                                public void run() {
                                    test2.setText(line);
                                }
                            });
                        }
                        break;
                    } catch (Exception e) {
                        handler.post(new Runnable() {
                            public void run() {
                                test.setText("傳送失敗");
                            }
                        });
                    }
                }
            }catch(IOException e){
                handler.post(new Runnable() {
                    public void run() {
                        test.setText("建立socket失敗");
                    }
                });
            }
        }
    };
}

最後記得要加上權限

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

歡迎轉載,請註明出處。




7 則留言:

  1. 作者已經移除這則留言。

    回覆刪除
  2. 想問一下這個範例是針對android 傳給androdi 嗎?
    因為我現在想用PC傳給android,可是卻一直卡在line = in.readUTF();這行
    因為我下面有寫println 結果東西傳進來連println都沒有動作
    想問一下 Jing Xun Chen 大有發生過類似的情形嗎?

    回覆刪除
    回覆
    1. 您好 :
      N acicor,發生您所說一直會卡在這一段(line = in.readUTF();)通常是等不到相關參數所造成的,如果可以的畫是否C端跟S端都用Android看看??

      刪除
    2. 我也遇到這樣的問題過,
      有網友分享文提及相關問題:
      後來於PC Sever發出的訊息尾端加入“\n",
      Android Client就能正常收到訊息了!

      刪除
  3. 作者已經移除這則留言。

    回覆刪除
  4. 你好:
    請教一下,此範例只顯示第一次收到資料
    那如果我要不斷接收,並顯示,該如何修改?

    回覆刪除
  5. 我與上面那個人有一樣的問題

    此範例只顯示第一次收到資料
    那如果我要不斷接收,並顯示,該如何修改?
    謝謝您

    回覆刪除