度娘給出的描述:
通常也稱作"通訊端",用於描述IP地址和連接埠,是一個通訊鏈的控制代碼。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並綁定到一個連接埠上,不同的連接埠對應於不同的服務。
網路上的兩個程式通過一個雙向的通訊串連實現資料的交換,這個雙向鏈路的一端稱為一個Socket。Socket通常用來實現客戶方和服務方的串連。Socket是TCP/IP協議的一個十分流行的編程介面,一個Socket由一個IP地址和一個連接埠號碼唯一確定。
在java中,Socket和ServerSocket類庫位於java .net包中。ServerSocket用於伺服器端,Socket是建立網路連接時使用的。在串連成功時,應用程式兩端都會產生一個Socket執行個體,操作這個執行個體,完成所需的會話。
下面通過一個極為簡單的用戶端和服務端的串連例子示範下最基本的android socket通訊:
服務端的代碼,在服務端特定的連接埠9999監聽用戶端請求,一旦有請求,便會執行,而後繼續監聽。使用accept()這個阻塞函數,就是該方法被調用後一直等待用戶端的請求,直到有請求且串連到同一個連接埠,accept()返回一個對應於用戶端的Socket。本例中很簡單,服務端不斷監聽,一旦有請求就輸出一段資訊:
[java]
<SPAN style="FONT-FAMILY: Comic Sans MS; FONT-SIZE: 18px">import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
private static final int PORT = 9999;
public static void main(String[] args) {
try {
// 執行個體化伺服器通訊端 設定連接埠號碼9999
ServerSocket server = new ServerSocket(PORT);
while (true) {
Socket socket = server.accept();
// 擷取輸出資料流
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
// 寫字串
writer.write("這是一段來自伺服器的問候:Hello沃德!");
writer.flush();
writer.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
</SPAN>
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
private static final int PORT = 9999;
public static void main(String[] args) {
try {
// 執行個體化伺服器通訊端 設定連接埠號碼9999
ServerSocket server = new ServerSocket(PORT);
while (true) {
Socket socket = server.accept();
// 擷取輸出資料流
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
// 寫字串
writer.write("這是一段來自伺服器的問候:Hello沃德!");
writer.flush();
writer.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
下面是android用戶端的相關內容,介面有一個按鈕,點擊後請求服務端的制定連接埠,然後顯示服務端的內容,值得注意的是在android4.0以上的系統中,是不允許在主線程裡面去執行網路相關的請求,否則會報錯:NetworkOnMainThreadException,所以本例中新開闢一個線程初始化socket的內容:
[java]
<SPAN style="FONT-FAMILY: Comic Sans MS; FONT-SIZE: 18px">package com.example.socketdemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
@SuppressLint("HandlerLeak")
public class SocketDemo extends Activity {
/** Called when the activity is first created. */
private Button btn_receive;
private TextView txt;
private String line;
private static final String HOST = "192.168.1.101";
private static final int PORT = 9999;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initControl();
}
private void initControl() {
btn_receive = (Button) findViewById(R.id.btn_receive);
txt = (TextView) findViewById(R.id.txt);
btn_receive.setOnClickListener(new ReceiverListener());
}
@SuppressLint("HandlerLeak")
class ReceiverListener implements OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread() {
@Override
public void run() {
// 執行完畢後給handler發送一個空訊息
try {
// 執行個體化Socket
Socket socket = new Socket(HOST, PORT);
// 獲得輸入資料流
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
line = br.readLine();
br.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.sendEmptyMessage(0);
}
}.start();
}
}
// 定義Handler對象
private Handler handler = new Handler() {
@Override
// 當有訊息發送出來的時候就執行Handler的這個方法
public void handleMessage(Message msg) {
super.handleMessage(msg);
// 處理UI
txt.setText(line);
Log.i("PDA", "----->" + line);
}
};
}
</SPAN>
package com.example.socketdemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
@SuppressLint("HandlerLeak")
public class SocketDemo extends Activity {
/** Called when the activity is first created. */
private Button btn_receive;
private TextView txt;
private String line;
private static final String HOST = "192.168.1.101";
private static final int PORT = 9999;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initControl();
}
private void initControl() {
btn_receive = (Button) findViewById(R.id.btn_receive);
txt = (TextView) findViewById(R.id.txt);
btn_receive.setOnClickListener(new ReceiverListener());
}
@SuppressLint("HandlerLeak")
class ReceiverListener implements OnClickListener {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread() {
@Override
public void run() {
// 執行完畢後給handler發送一個空訊息
try {
// 執行個體化Socket
Socket socket = new Socket(HOST, PORT);
// 獲得輸入資料流
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
line = br.readLine();
br.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
handler.sendEmptyMessage(0);
}
}.start();
}
}
// 定義Handler對象
private Handler handler = new Handler() {
@Override
// 當有訊息發送出來的時候就執行Handler的這個方法
public void handleMessage(Message msg) {
super.handleMessage(msg);
// 處理UI
txt.setText(line);
Log.i("PDA", "----->" + line);
}
};
}
如下:
另外在設定檔中記得加上許可權:<uses-permission android:name="android.permission.INTERNET">
測試的時候先啟動服務端,然後啟動用戶端,點擊按鈕就可擷取到服務端資訊。這是在是一個灰常簡單的有關android socket的小例子,可以初步對socket有個簡單的瞭解,這個筆記就先記到這裡!