亂打一通的心情日記

跳到主文

程式‧生活‧旅行

部落格全站分類:數位生活

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 3月 28 週三 201223:50
  • [Android] Android 學習筆記:開啟一個 server socket

如果想讓 app 可以開一個 port 等待外界傳資料進來,應該要怎麼做呢?

其實這個跟 Android 沒什麼關係,而是用 Java 的 ServerSocket 元件就可以作到了

只是因為 server socket 在 accept() 的時候,執行緒會卡住,

因此應該要開一個新的執行緒來執行

 

下面的程式片段開了一個 8888 的 server port,

接著啟動一個新的執行緒 MyServerThread 來做接下來的動作

(這裡的 MyServerThread 是一個繼承自 Thread 的類別)

要注意的是 socket 的動作通常都需要用 try/catch 包起來,

因為有丟 exception 的可能性

try
{
    // Open a server socket
    int nServerPort = 8888;
    m_serverSocket = new ServerSocket(nServerPort);
   
    // Start a server thread to do socket-accept tasks
    MyServerThread serverThread = new MyServerThread(MyActivity.this);
    serverThread.start();
}
catch (IOException e)
{
    e.printStackTrace();
} 

 

要關閉 server socket 也很容易,呼叫 close() 就可以了:

try
{
    // Close server socket
    m_serverSocket.close();
}
catch (IOException e)
{
    e.printStackTrace();
}        

 

等待接收 client 連線的部分,呼叫 accept() 函式就可以了

Socket socketClient = m_serverSocket.accept();

 

下面的範例程式是一個較完整的程式,當按下 ToggleButton 時,

會開啟 server socket 聽在 8888 port,再按一下則會關閉 

 

MyActivity.java:

package com.my;

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

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

import com.my.R;

public class MyActivity extends Activity {
   
    // Public variables
    public ServerSocket     m_serverSocket      = null;

    // Private Controls
    private ToggleButton    m_toggleButtonServerOnOff;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        // Initialize control variables
        m_toggleButtonServerOnOff       = (ToggleButton)findViewById(R.id.toggleButtonServerOnOff);
       
        // Set listener functions
        m_toggleButtonServerOnOff.setOnClickListener(onToggleServerOnOff);
    }
   
    private Button.OnClickListener onToggleServerOnOff = new Button.OnClickListener(){
        public void onClick(View v)
        {
            if (m_toggleButtonServerOnOff.isChecked())
            {
                try
                {
                    // Open a server socket
                    int nServerPort = 8888;
                    m_serverSocket = new ServerSocket(nServerPort);
                   
                    // Start a server thread to do socket-accept tasks
                    MyServerThread serverThread = new MyServerThread(MyActivity.this);
                    serverThread.start();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            else
            {
                try
                {
                    // Close server socket
                    m_serverSocket.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }              
            }
        }
    };
}

 

另一段則是真正在接收 socket 連線的 MyServerThread 的程式

它在建構式裡先把 activity 的指標存起來,

接著覆寫 run() 函式,呼叫 ServerSocket::accept() 函式來等待 client 的連線

當連線成功時,用 DataInputStream 把送進來的文字資訊一行行讀出來,

並輸出到 logging 機制去

 

MyServerThread.java:

/**
 *
 */

package com.my;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import android.util.Log;

public class MyServerThread extends Thread {

    private static final String LOG_TAG = "MyServerThread";
   
    private MyActivity  m_activityMain;
   
    public MyServerThread(MyActivity activityMain)
    {
        super();
       
        // Save the activity
        m_activityMain = activityMain;
    }

    @Override
    public void run()
    {
        while (true)
        {
            try
            {
                // Wait for new client connection
                Log.i(LOG_TAG, "Waiting for client connection...");
                Socket socketClient = m_activityMain.m_serverSocket.accept();
               
                Log.i(LOG_TAG, "Accepted connection from " + socketClient.getInetAddress().getHostAddress());
                       
                // Read input from client socket
                InputStream is = socketClient.getInputStream();
                OutputStream os = socketClient.getOutputStream();
                DataInputStream dis = new DataInputStream(is);
                while (!socketClient.isClosed())
                {
                    // Read a line
                    String sLine = dis.readLine();
                    Log.i(LOG_TAG, "Read client socket=[" + sLine + "]");
                    if (sLine == null)
                    {
                        break;
                    }
                }
               
                // Close streams
                dis.close();
                os.close();
                is.close();
               
                // Close client socket
                Log.i(LOG_TAG, "Read data from client ok. Close connection from " + socketClient.getInetAddress().getHostAddress());
                socketClient.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
           
            // Stop loop when server socket is closed
            if (m_activityMain.m_serverSocket.isClosed())
            {
                break;
            }
        }
    }

}

 

 

文章標籤
全站熱搜
創作者介紹
創作者 ephrain 的頭像
ephrain

亂打一通的心情日記

ephrain 發表在 痞客邦 留言(0) 人氣(32,696)

  • 全站分類:
  • 個人分類:Android
▲top

ADSENSE

喜歡的動漫圖片

個人資訊

ephrain
暱稱:
ephrain
分類:
數位生活
好友:
累積中
地區:

文章搜尋

最新文章

    熱門文章

    • ()[Android] Android 學習筆記:開啟一個 server socket
    • ()[Android-x86] 用 Android-x86 在 PC 上執行 Android
    • ()[MOD] 自己安裝與設定中華電信 MOD
    • ()[Android] 使用 TeamViewer QuickSupport 遠端遙控手機
    • ()[Android] 將 HTC Incredible S Root 與刷機!
    • ()[Mac/Chrome] 將 https 網站加入 Chrome 的信任清單
    • ()[育兒] 新生兒報戶口、申請生育獎勵金、育兒津貼、國民年金生育給付、有照片的健保卡
    • ()[Sublime Text] 讓 Sublime Text 支援 BIG5 編碼的文字檔
    • ()[Windows] 使用 start 指令在批次檔中啟動程式
    • ()[Python] 在函式裡使用全域變數要加 global

    最新留言

    文章分類

    toggle 藝文 (4)
    • 電影.動畫 (0)
    • 音樂會 (0)
    • 展覽.講座 (0)
    • 樂讀 (0)
    toggle 旅遊 (10)
    • 日本.關西 (0)
    • 台灣‧北部 (0)
    • 台灣‧中部 (0)
    • 台灣‧南部 (0)
    • 台灣‧東部 (0)
    • 美國 (0)
    • 韓國.濟州島 (0)
    • 香港 (0)
    • 柬埔寨.吳哥窟 (0)
    • 大陸 (0)
    toggle 電腦技術 (29)
    • Web (0)
    • Debug/Performance (0)
    • Windows (0)
    • Linux (0)
    • Android (0)
    • C (0)
    • Virtualization (0)
    • Database (0)
    • Perl (0)
    • AutoIt (0)
    • PHP (0)
    • Python (0)
    • Mac (0)
    • Chrome (0)
    • Security (0)
    • Editor (0)
    • VBScript (0)
    • Java (0)
    • Cordova (0)
    • XML (0)
    • Network (0)
    • CVS (0)
    • Algorithm (0)
    • Scratch (0)
    • App Inventor (0)
    • PowerShell (0)
    • Hardware (0)
    • iPhone (0)
    • Agile (0)
    toggle 個人 (7)
    • 流水 (0)
    • 聚會.食記 (0)
    • 心情 (0)
    • 教會 (0)
    • 寵物 (0)
    • 亂煮 (0)
    • 家庭 (0)
    • 未分類文章 (1)

    By Eph

    ephrain
    PIXNET Logo登入

    參觀人氣

    • 本日人氣:0
    • 累積人氣:1,749,183