天天看點

Android學習筆記-網絡程式設計

1.使用UDP協定傳輸資料

UDP協定不可靠,資料包發送出去之後無法确定是否被接收方接收到

在Java裡寫好Server如下

package com.umgsai.server;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Calendar;
import java.util.Date;

public class Server {
	static Date date ;
	public static void main(String[] args) {
		while (true) {
			try {
				// 建立一個DatagramSocket對象,并指定監聽的端口号
				DatagramSocket socket = new DatagramSocket(4572);
				byte data[] = new byte[1024];
				// 建立一個空的DatagramPacket對象
				DatagramPacket packet = new DatagramPacket(data, data.length);
				// 使用receive方法接收用戶端所發送的資料
				socket.receive(packet);
				String result = new String(packet.getData(),
						packet.getOffset(), packet.getLength());
				date = Calendar.getInstance().getTime();
				System.out.println(date);
				System.out.println("result--->" + result);
				socket.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}      

用戶端在Android裡面編寫

界面activity_main.xml

  <Button 
	android:id="@+id/sendMessage"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="發送消息"
    />      

Android4.0+作業系統中連接配接網絡的操作不能在主線程中進行

public class MainActivity extends Activity {

	private Button sendMessage = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		sendMessage = (Button) findViewById(R.id.sendMessage);
		sendMessage.setOnClickListener(new clientListener());
		
	}

	class clientListener implements OnClickListener{

		@Override
		public void onClick(View v) {
			HandlerThread handlerThread = new HandlerThread("handler_Thread");
            handlerThread.start();
            ClientHandler clientHandler = new ClientHandler(handlerThread.getLooper());
            Message msg = clientHandler.obtainMessage();
            Bundle bundle = new Bundle();
            msg.setData(bundle);
            // 将msg發送到目标對象,即生成msg對象的Handler對象
            msg.sendToTarget();
		}
		
	}
	
	class ClientHandler extends Handler {
        public ClientHandler() {
 
        }
 
        public ClientHandler(Looper looper) {
            super(looper);
        }
 
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Bundle bundle = msg.getData();
            try {
				// 首先建立一個DatagramSocket對象
				DatagramSocket socket = new DatagramSocket(4572);
				// 建立一個InetAddree
				InetAddress serverAddress = InetAddress.getByName("192.168.77.215");
				String str = "hello";
				byte data[] = str.getBytes();
				// 建立一個DatagramPacket對象,并指定要講這個資料包發送到網絡當中的哪個位址,以及端口号
				DatagramPacket packet = new DatagramPacket(data,
						data.length, serverAddress, 4572);
				// 調用socket對象的send方法,發送資料
				socket.send(packet);
				socket.close();
				Toast.makeText(MainActivity.this, "資料已發送", Toast.LENGTH_SHORT).show();
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
        }
    }
}      

用戶端需要的權限

  <uses-permission android:name="android.permission.INTERNET" />      

TCP協定是可靠的協定

TCPServer.java

public class TCPServer {
	public static void main(String[] args) throws IOException {
		ServerSocket listen = new ServerSocket(5050);

		Socket server = listen.accept();

		InputStream in = server.getInputStream();
		OutputStream out = server.getOutputStream();

		char c = (char) in.read();
		System.out.println("收到:" + c);

		out.write('s');

		out.close();
		in.close();
		server.close();
		listen.close();
	}

}      

TCPClient.java

public class TCPClient {
	public static void main(String[] args) throws IOException {
		Socket client = new Socket("127.0.0.1", 5050);

		InputStream in = client.getInputStream();
		OutputStream out = client.getOutputStream();

		out.write('c');

		char c = (char) in.read();
		System.out.println("收到:" + c);

		out.close();
		in.close();
		client.close();
	}

}      

Socket程式設計與Android作業系統無關,使用的是Java.net包裡的類。

在Android裡面進行網絡程式設計的時候要注意不能将連接配接網絡的代碼放到主線程裡。

PS:在非UI線程裡顯示Toast的時候要按照下面的方式寫

Looper.prepare();
Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
Looper.loop();      

Mars視訊提供的TCP例子如下

Server端

class ServerThread extends Thread {
		public void run(){
		//聲明一個ServerSocket對象
		ServerSocket serverSocket = null;
		try {
			//建立一個ServerSocket對象,并讓這個Socket在4567端口監聽
			serverSocket = new ServerSocket(4567);
			//調用ServerSocket的accept()方法,接受用戶端所發送的請求
			Socket socket = serverSocket.accept();
			//從Socket當中得到InputStream對象
			InputStream inputStream = socket.getInputStream();
			byte buffer [] = new byte[1024*4];
			int temp = 0;
			//從InputStream當中讀取用戶端所發送的資料
			while((temp = inputStream.read(buffer)) != -1){
				System.out.println(new String(buffer,0,temp));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			try {
				serverSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	
	}
}      

Client端

public class TCPClient {
	public static void main(String[] args) {
		try {
			//建立一個Socket對象,指定伺服器端的IP位址和端口号
			Socket socket = new Socket("192.168.1.104",4567);
			//使用InputStream讀取硬碟上的檔案
			InputStream inputStream = new FileInputStream("f://file/words.txt");
			//從Socket當中得到OutputStream
			OutputStream outputStream = socket.getOutputStream();
			byte buffer [] = new byte[4*1024];
			int temp = 0 ;
			//将InputStream當中的資料取出,并寫入到OutputStream當中
			while((temp = inputStream.read(buffer)) != -1){
				outputStream.write(buffer, 0, temp);
			}
			outputStream.flush();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}      

在調試的時候抛如下異常,暫未解決

java.net.SocketException: Connection reset

at java.net.SocketInputStream.read(Unknown Source)

繼續閱讀