[Android] Android 學習筆記:開啟一個 server socket

如果想讓 app 可以開一個 port 等待外界傳資料進來,應該要怎麼做呢?
其實這個跟 Android 沒什麼關係,而是用 Java 的 ServerSocket 元件就可以作到了~
只是因為 server socket 在 accept() 的時候,執行緒會卡住,
因此應該要開一個新的執行緒來執行~
下面的程式片段開了一個 8888 的 server port,
接著啟動一個新的執行緒 MyServerThread 來做接下來的動作~
(這裡的 MyServerThread 是一個繼承自 Thread 的類別)
要注意的是 socket 的動作通常都需要用 try/catch 包起來,
因為有丟 exception 的可能性~
{
// 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() 就可以了:
{
// Close server socket
m_serverSocket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
等待接收 client 連線的部分,呼叫 accept() 函式就可以了~
下面的範例程式是一個較完整的程式,當按下 ToggleButton 時,
會開啟 server socket 聽在 8888 port,再按一下則會關閉~
MyActivity.java:
 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;
             }
         }
     }
}
2 thoughts on “[Android] Android 學習筆記:開啟一個 server socket”
版主您好,再server端部分怎麼沒有看到綁port 的code 呢?
版主回覆:(03/06/2015 03:16:24 PM)
嗯?下面這個就是囉:
// Open a server socket
int nServerPort = 8888;
m_serverSocket = new ServerSocket(nServerPort);
版主您好~
請問 ServerSocket 有辦法測量出傳輸的頻寬多大嗎?