1. android Socket一個 BufferedReader讀取問題
1,網路編程傳輸的數據都是以二進制格式來傳輸的。2,所以傳輸流第一層必須使用位元組流而不能使用字元流3,後面就可以使用BufferedReader套接在位元組流外層了例:BufferedReaderclientReader=newBufferedReader(newInputStreamReade(socket.getInputStream()));//讀數據PrintStreamprintStream=newPrintStream(socket.getOutputStream());//發送數據printStream.println("xxxxxxx");發送一個帶換行符的數據clientReader.readline();//接收帶換行符的數據4,您也可以試試使用BufferedInputStream。
2. Android ParcelFileDescriptor實現進程間通信
一個通信通道,實現跨進程的的Socket網路通信。
具體的通信通道的圖如下。
android進程間通信是使用Binder來傳數據,而Binder傳輸的數據,有一個最為基本的要求,就是要實現Parcelable介面。
ParcelFileDescriptor是android提供的一個數據結構。
ParcelFileDescriptor是可以用於進程間Binder通信的FileDescriptor。支持stream 寫入和stream 讀出
我們可以使用
來將PacecelFileDescriptor 與File對應起來,以實現進程間的文件共享。
我們也可以使用
來建立一個pipe通信通道,ParcelFileDescriptor數組第一個元素是read端,第二個元素是write端,通過write端的AutoCloseOutputStream和read端的AutoCloseInputStream,我們就可以實現進程見的數據流傳輸了。
發送端:
1. 業務層調用getOutputStream向通信層發起請求
2. 通信層通過creatPipe 建立一個ParcelFileDescriptor數組,並將write端的pipe[1]返回給業務層
3. 業務層得到pipe[1](ParcelFileDescriptor)後,可以通過AutoCloseOutputStream寫入數據
4. 從通信層的pipe[0]的AutoCloseInputStream中讀出數據通過socket發送出去
接收端:
1. 業務層調用getInputStream向通信層發起請求
2. 通信層通過creatPipe 建立一個ParcelFileDescriptor數組,並將read端的pipe[0]返回給業務層
3. 業務層得到pipe 0 後,可以通過AutoCloseInputStream讀取數據。(如沒有數據,則阻塞,一直等到有數據為止)
4. socket中讀取數據,寫入到通信層的pipe[1]的AutoCloseOutputStream。(pipe[1]一旦寫入,第三步中pipe[2]就可以讀取出數據)
3. android socket外網
首先,外網訪問的前提是你的外網地址必須是固定的。在路由器上設置埠映射是實現這一目標的一種方法,不過部分路由器可能不直接提供這一功能。假設你在區域網內的伺服器地址是192.168.2.3,並且埠為4000,那麼你可以在上網的路由器上設置埠映射,將外部埠XXXX映射到192.168.2.3的4000埠。這樣一來,當你對外網的固定地址XXXX發起socket連接時,實際連接會被轉發到192.168.2.3的4000埠上,與平時的socket連接沒有區別。
對於動態IP地址的情況,可以使用花生殼服務來解決。花生殼服務能夠根據你的動態IP地址自動調整訪問的路由,你只需通過訪問花生殼提供的域名,就可以自動指向你的動態IP地址。這樣一來,無論你的IP地址如何變化,都可以保持穩定的訪問。
關於java中通過域名獲取IP地址的方法,可以使用以下代碼片段實現:
java
public InetAddress[] getServerIP(String domain) {
try {
InetAddress[] myServer = InetAddress.getAllByName(domain);
return myServer;
} catch (UnknownHostException e) {
e.printStackTrace();
}
return null;
}
這段代碼通過傳入的域名獲取到對應的IP地址數組。請注意,這段代碼是從網上復制的,雖然看起來是正確的,但在使用前建議進行編譯測試,確保其正確性。
總之,通過合理設置埠映射和使用花生殼服務,可以很好地解決Android應用在socket連接中的外網訪問問題。在實際應用中,根據不同的需求選擇合適的方法是非常重要的。
4. android socket有幾種方法
/***第一種:客戶端Socket通過構造方法連接伺服器***/
//客戶端Socket可以通過指定IP地址或域名兩種方式來連接伺服器端,實際最終都是通過IP地址來連接伺服器
//新建一個Socket,指定其IP地址及埠號
Socket socket = new Socket("192.168.0.7",80);
/***Socket 客戶端 一些常用設置***/
//客戶端socket在接收數據時,有兩種超時:1.連接伺服器超時,即連接超時;2.連接伺服器成功後,接收伺服器數據超時,即接收超時
//*設置socket 讀取數據流的超時時間
socket.setSoTimeout(5000);
//發送數據包,默認為false,即客戶端發送數據採用Nagle演算法;
//但是對於實時交互性高的程序,建議其改為true,即關閉Nagle演算法,客戶端每發送一次數據,無論數據包大小都會將這些數據發送出去
socket.setTcpNoDelay(true);
//設置客戶端socket關閉時,close()方法起作用時延遲1分鍾關閉,如果1分鍾內盡量將未發送的數據包發送出去
socket.setSoLinger(true, 60);
//設置輸出流的發送緩沖區大小,默認是8KB,即8096位元組
socket.setSendBufferSize(8096);
//設置輸入流的接收緩沖區大小,默認是8KB,即8096位元組
socket.setReceiveBufferSize(8096);
//作用:每隔一段時間檢查伺服器是否處於活動狀態,如果伺服器端長時間沒響應,自動關閉客戶端socket
//防止伺服器端無效時,客戶端長時間處於連接狀態
socket.setKeepAlive(true);
/*** Socket客戶端向伺服器端發送數據 ****/
//客戶端向伺服器端發送數據,獲取客戶端向伺服器端輸出流
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//代表可以立即向伺服器端發送單位元組數據
socket.setOOBInline(true);
//數據不經過輸出緩沖區,立即發送
socket.sendUrgentData(65);//"A"
//向伺服器端寫數據,寫入一個緩沖區
//註:此處字元串最後必須包含「\r\n\r\n」,告訴伺服器HTTP頭已經結束,可以處理數據,否則會造成下面的讀取數據出現阻塞
//在write()方法中可以定義規則,與後台匹配來識別相應的功能,例如登錄Login()方法,可以寫為write("Login|test,123 \r\n\r\n"),供後台識別;
bw.write("Login|test,123 \r\n\r\n");
//發送緩沖區中數據,必須有
bw.flush();
/*** Socket客戶端讀取伺服器端響應數據 ****/
//socket.isConnected代表是否連接成功過
if((socket.isConnected() == true) && (socket.isClosed() == false)){//判斷Socket是否處於連接狀態
//客戶端接收伺服器端的響應,讀取伺服器端向客戶端的輸入流
InputStream is = socket.getInputStream();
//緩沖區
byte[] buffer = new byte[is.available()];
//讀取緩沖區
is.read(buffer);
//轉換為字元串
String responseInfo = new String(buffer);
//日誌中輸出
Log.i("TEST", responseInfo);
} //關閉網路
socket.close();
/***第二種:通過connect方法連接伺服器***/
Socket socket_other = new Socket();
//使用默認的連接超時
socket_other.connect(new InetSocketAddress("192.168.0.7",80));
//連接超時2s
socket_other.connect(new InetSocketAddress("192.168.0.7",80),2000);
//關閉socket
socket_other.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}