[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 有辦法測量出傳輸的頻寬多大嗎?