1. 程式人生 > >android 通過區域網udp廣播自動建立socket連線

android 通過區域網udp廣播自動建立socket連線

android開發中經常會用到socket通訊。由於專案需要,最近研究了一下這方面的知識。 需求是想通過wifi實現android移動裝置和android平臺的電視之間的檔案傳輸與控制。 毫無疑問這中間一定需要用到socket來進行通訊。今天就兩臺裝置的握手連線方式分享一下吧,該方法只是本人個人想法的實現,僅供參考,如有雷同,不勝榮幸。

   要想使用socket進行通訊,就必須知道服務端的IP地址,我使用的是通過udp局網廣播來實現局網內服務端的搜尋建立連線。以下是程式碼實現。

   首先是客戶端:

public class MainActivity extends Activity {
	/*傳送廣播端的socket*/
	private MulticastSocket ms;
	/*傳送廣播的按鈕*/
	private Button sendUDPBrocast;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		init();
	}
	
	/*初始化引數*/
	public void init() {
		setContentView(R.layout.main);
		sendUDPBrocast = (Button) findViewById(R.id.send);
		sendUDPBrocast.setOnClickListener(new SendUDPBrocastListener());
		try {
			/*建立socket例項*/
			ms = new MulticastSocket();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 單擊按鈕時,傳送區域網廣播
	 * */
	class SendUDPBrocastListener implements OnClickListener{
		
		@Override
		public void onClick(View v) {
			//傳送的資料包,局網內的所有地址都可以收到該資料包
			DatagramPacket dataPacket = null;
			try {
				ms.setTimeToLive(4);
				//將本機的IP(這裡可以寫動態獲取的IP)地址放到資料包裡,其實server端接收到資料包後也能獲取到發包方的IP的
				byte[] data = "192.168.1.101".getBytes();
				//224.0.0.1為廣播地址
				InetAddress address = InetAddress.getByName("224.0.0.1");
				//這個地方可以輸出判斷該地址是不是廣播型別的地址
				System.out.println(address.isMulticastAddress());
				dataPacket = new DatagramPacket(data, data.length, address,
						8003);
				ms.send(dataPacket);
				ms.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
   以下是服務端:
public class MainActivity extends Activity implements Runnable {
	private MulticastSocket ds;
	String multicastHost="224.0.0.1";
	InetAddress receiveAddress;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		try {
			ds = new MulticastSocket(8003);
			receiveAddress=InetAddress.getByName(multicastHost);
			ds.joinGroup(receiveAddress);
			new Thread(this).start();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		byte buf[] = new byte[1024];
		DatagramPacket dp = new DatagramPacket(buf, 1024);
		while (true) {
			try {
				ds.receive(dp);
				//Toast.makeText(this, new String(buf, 0, dp.getLength()), Toast.LENGTH_LONG);
				System.out.println("client ip : "+new String(buf, 0, dp.getLength()));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
   這樣一來如果移動裝置所連線的局網記憶體在socket的服務端,服務端就會接收到客戶端發出的廣播,然後服務端再通過接收到的IP與客戶端進行連線進而就可以進行控制及檔案的傳輸了。需要注意的是,udp廣播會導致局網傳輸速度變慢,而且udp為不可靠協議,發出的廣播服務端不一定都能夠收到,所以在實際情況中需要做很多邏輯處理,比如線上程裡發廣播直到收到服務端的迴應 但如果局網內不存在服務端就會陷入死迴圈,所以這時就要做限時操作了等等。。。  具體的看個人需求而言了吧。