網路相關

      在〈網路相關〉中尚無留言

查詢網域ip

有了DNS/DDNS,為何還要想要由網域查詢 ip呢! 原因是像華碩路由器所提供的動態轉址功能,時好時壞的。所以如果能第一次先查詢到 ip,後續直接由 ip 來進線的話,就不用怕 DDNS時好時壞的問題了。

首先由 InetAddress傳入網域名稱,再取得 hostName即可取得 ip的字串。

請注意這段程式碼一定要在新 Thread中執行,若使用 UI Thread執行,InetAddress.getByName會取得 null 物件。

fun getIp(){
    Thread {
        try {
            G.ip = InetAddress.getByName(G.hostName).hostName
            handler.sendEmptyMessage(G.HostSuccess)
        }
        catch (e: Exception) {
            handler.sendEmptyMessage(G.HostError)
        }
    }.start()
}

todo

傳送GET資料

Android 大都會使用 Http 協議來訪問網絡, Android 主要提供了兩種方式,分別為 HttpURLConnection及 HttpClient。在Android6.0版本中 HttpClient 已經被移除。而且HttpURLConnection是由 Google所開發,效能高, Bug 少,所以當然是要使用 HttpURLConnection。

先產生 URL物件,再由 url.openConnection產生 HttpURLConnection物件。連線後的結果,可由conn.inputStream進行讀取。

conn.readTimeout=5000 可防止網路臨時中斷而進入孤立連線,單位為ms。也就是說5秒後,沒有取得回應,就會發生 Exception。

當由 conn.inputStream 取得 InputStream 物件時,系統會先自動觸發 conn.connect()函數開始執行連線。然後就可以由 inputStream讀取回應了。

Thread{
try {
val cmd =
"http://${G.ip}/dispatch/delete_case.php?id=%s".format(roadcase["id"])
val url = URL(cmd)
val conn = url.openConnection() as HttpURLConnection
conn.requestMethod = "GET"
conn.readTimeout = 5000
conn.doInput=true
val inputStream = conn.inputStream
val br = BufferedReader(InputStreamReader(inputStream, "UTF-8"))
var lines=StringBuffer()
do{
val line=br.readLine()
if(line==null)break
lines.append(line)
}while(true)
if (lines.contains("success")) {
handler.sendEmptyMessage(What_success)
} else {
handler.sendEmptyMessage(What_delete_error)
}
}
catch(e:Exception){
handler.sendEmptyMessage(What_Internet_error)
}

}.start()

todo

傳送POST資料

POST 則是多了 DataOutputStream 連線,將要傳遞的資料,傳入 dos中。

大部份的網站都說,要傳送純文字資料,必需將 Content-Type 設定為 “application/x-www-form-urlencoded”。但本人測試的結果,要嘛就是不要設定,不然就要設定為 null。

//conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
conn.setRequestProperty("Content-Type", null)

底下為完整代碼

Thread{
    try{
        val url=URL("http://${G.ip}/dispatch/test.php")
        val conn=url.openConnection() as HttpURLConnection
        conn.readTimeout=5000
        conn.connectTimeout=5000
        conn.doInput=true
        conn.doOutput=true
        conn.useCaches=false
        conn.requestMethod="POST"
        conn.setRequestProperty("Connection", "Keep-Alive")
        conn.setRequestProperty("Charset", "utf-8")
        conn.setRequestProperty("Content-Type", null)
        val dos= DataOutputStream(conn.outputStream)
        var sb=StringBuffer()
        sb.append("userAccount=")
        sb.append(URLEncoder.encode("張無忌", "UTF-8"))
        dos.writeBytes(sb.toString())
        val inputStream=conn.inputStream
        val br = BufferedReader(InputStreamReader(inputStream, "UTF-8"))
        var lines=StringBuffer()
        do{
            var line = br.readLine()
            if (line==null)break
            lines.append(line)
        }while(true)

        Log.d("Thomas", lines.toString())
        dos.flush()
        dos.close()
        if (lines.contains("success"))handler.sendEmptyMessage(G.Pothole_upload_success)
        else handler.sendEmptyMessage(G.Pothole_upload_error)
    }
    catch(e:Exception){
        handler.sendEmptyMessage(G.Pothole_upload_timeout)
    }
}.start()

傳送POST圖片

下面的例子,是將圖片讀入,然後寫入到 dos中。至於文字資料,則採用 GET的方式由網址傳入。

val url=URL("http://${G.ip}/dispatch/upload_pothole.php?id=${id}")
Thread{
    try{
        val lineEnd="\r\n"
        val prefix="--"
        val boundary= UUID.randomUUID().toString()
        val maxBufferSize=1*1024*1024
        val file=File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "%s/%s".format(G.photoDir,fileName))
        val fis=FileInputStream(file)
        val conn=url.openConnection() as HttpURLConnection
        conn.readTimeout=5000
        conn.connectTimeout=5000
        conn.doInput=true
        conn.doOutput=true
        conn.useCaches=false
        conn.requestMethod="POST"
        conn.setRequestProperty("Connection", "Keep-Alive")
        conn.setRequestProperty("Charset", "utf-8")
        conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary)
        val dos= DataOutputStream(conn.outputStream)
        dos.writeBytes(prefix + boundary + lineEnd)
        dos.writeBytes(String.format("Content-Disposition: form-data; name=\"file\";filename=\"%s\"%s", fileName, lineEnd))
        dos.writeBytes(lineEnd)
        var bytesAvailable=fis.available()
        var bufferSize=Math.min(bytesAvailable, maxBufferSize)
        val buffer=ByteArray(bufferSize)
        var bytesRead=fis.read(buffer, 0, bufferSize)
        while(bytesRead>0){
            dos.write(buffer, 0, bufferSize)
            bytesAvailable=fis.available()
            bufferSize=Math.min(bytesAvailable, maxBufferSize)
            bytesRead=fis.read(buffer, 0, bufferSize)
        }
        dos.writeBytes(lineEnd)
        dos.writeBytes(prefix + boundary + prefix + lineEnd)
        val inputStream=conn.inputStream
        val br = BufferedReader(InputStreamReader(inputStream, "UTF-8"))
        var lines=StringBuffer()
        do{
            var line = br.readLine()
            if (line==null)break
            lines.append(line)
        }while(true)
        fis.close()
        dos.flush()
        dos.close()
        if (webResponse.contains("success"))handler.sendEmptyMessage(G.Pothole_upload_success)
        else handler.sendEmptyMessage(G.Pothole_upload_error)
    }
    catch(e:Exception){
        handler.sendEmptyMessage(G.Pothole_upload_timeout)
    }
}.start()

todo

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *