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)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at com.umgsai.server.TCPServer.main(TCPServer.java:25)
未完待续...