天天看点

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)