回 Android手機程式設計人才培訓班 課程時間表

串流與通訊協定

用於網路Socket的串流物件

因為Java的標準化,基本上為使用Java標準輸出輸入(I/O)物件就可以了。

輸入

  • InputStream(由Socket物件getInputStream()方法取得。
  • InputStreamReader(以Byte的方式來讀取資料)。
  • BufferedReader(用來一次讀取一行字串)。

範例:
// 向伺服器讀取訊息的物件
InputStreamReader isr = null;

try
{
    isr = new InputStreamReader(s.getInputStream());
}
catch (IOException e)
{
    Log.d("ChattingRoom:Client", e.getMessage());
}

// 用來一次讀取一條指令的物件
BufferedReader br = new BufferedReader(isr);

while(true)
{
    if(s.isConnected())
    {
        String str = "";

        try
        {
        // 從伺服器一次讀取一行協定
        str = br.readLine();

        // 判斷是否已經和伺服器斷線了
        if(str == null)
        {
        s.close();
        break;
        }
        }
        catch (IOException e)
        {
        Log.d("ChattingRoom:Client", e.getMessage());
        break;
        }

        Log.d("ChattingRoom:Client", "Client received " + str);

        // ...處理資料程式碼...
    }
    else
    {
        Log.d("ChattingRoom:Client", "Disconnected");
    }
}

輸出

  • OutputStream(由Sokcet物件getOutputStream()方法取得。
  • OutputStreamWriter(以Byte的方式來輸出資料)。
  • PrintWriter(用來一次輸出一行字串)。

範例:
try
{
    Socket s = new Socket(ip, port);

    // 建立要用來輸入訊息到伺服器的物件
    OutputStreamWriter osr = new OutputStreamWriter(s.getOutputStream());
    BufferedWriter bw = new BufferedWriter(osr);
    out = new PrintWriter(bw);

    // 如果到這裡沒產生例外,表示連線成功,通知伺服器登入的使用者名字
    out.println(RoomProtocol.CLIENT_LOGIN + name);

    // 送出資料
    out.flush();
}
catch (UnknownHostException e)
{
    Log.d("ChattingRoom:Client", e.getMessage());
}
catch (IOException e)
{
    Log.d("ChattingRoom:Client", e.getMessage());
}

通訊協定

通常一個通訊協定用來定義Server或Client之間互相溝通的資料格式,如該資料封包的用途、長度、檢查碼等等。像HTTP、FTP等等就是基於該通訊協定實現的網路服務。

而通常私人用伺服器或遊戲伺服器為了節省資料流量且不需要與外界溝通,因此會定義自己的資料封包格式,也就是網路傳輸協定。

例如聊天室通訊協定:
// 通訊協定
public class RoomProtocol
{
    public static final int PORT = 9999;

    // Client -> Server: 登入
    public static final String CLIENT_LOGIN = "id:;:";

    // Client -> Server: 傳送訊息
    public static final String CLIENT_MESSAGE = "msg:;:";

    // Server -> Client: 新使用者上線
    public static final String SERVER_NEW_USER = "new:;:";

    // Server -> Client: 有事件通知Client
    public static final String SERVER_NOTIFICATION = "noti:;:";
}