在上一篇[android]一个关于UDP和TCP的项目实践(一)中已经交代了项目逻辑和基本知识点,这篇解释代码。首先需要加上如下权限:注意udp广播,和udp广播监听需要绑定同一个端口。<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
测试机的版本为4.4。UI设计的很简单,三个功能按钮分别为发送广播、停止发送广播以及清除Textview里的内容。按钮下面的两个TextView分别显示收到的udp请求和tcp请求以及发送的tcp请求信息,代码如下:MainActivity中开启两个线程,分别用来接收tcp连接和接收udp多播并发送tcp连接:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_horizontal" android:paddingTop="20dp" > <Button android:id="@+id/start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="start" /> <Button android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="60dp" android:text="stop" /> <Button android:id="@+id/clean" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="60dp" android:text="clean" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_horizontal" android:layout_weight="1" android:padding="20dp" > <TextView android:id="@+id/send_information" android:layout_marginTop="30dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.5" android:text="send" /> <TextView android:id="@+id/receive_information" android:layout_marginTop="30dp" android:text="receive" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.5" /> </LinearLayout> </LinearLayout>
/* 开一个线程接收tcp 连接*/ new tcpReceive(receive_label).start(); /* 开一个线程接收udp多播并发送tcp 连接*/ new udpReceiveAndtcpSend().start();
tcpRecieve的代码如下:package com.example.cxlveu.udpreceiveandtcpsend; import android.util.Log; import android.widget.TextView; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * Created by cxlveu on 16/4/8. */ /* 接收tcp连接 */ public class tcpReceive extends Thread{ private final static String TAG = "Tcp Receive"; private ServerSocket serverSocket; private Socket socket; private BufferedReader br; private String source_address = ""; private TextView receive_label; public tcpReceive(TextView textView){ this.receive_label = textView; } @Override public void run(){ while (true){ serverSocket = null; socket = null; br = null; try { Log.i(TAG, " new ServerSocket start"); serverSocket = new ServerSocket(8080); socket = serverSocket.accept(); Log.i(TAG," get socket"); if(socket != null){ br = new BufferedReader(new InputStreamReader(socket.getInputStream())); StringBuilder sb = new StringBuilder(); sb.append(socket.getInetAddress().getAddress()); Log.i(TAG, sb.toString().trim()); String line = null; while ((line = br.readLine()) != null){ sb.append(line); } source_address = sb.toString().trim();receive_label.post(new Runnable() { @Override public void run() { receive_label.append("收到来自: " + "\n" + source_address + "\n" + "的tcp请求\n\n"); } }); } } catch (IOException e1) { e1.printStackTrace(); } finally { try { if (br != null) br.close(); if (socket != null) socket.close(); if (serverSocket != null) serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
udpReceiveAndtcpSend的代码如下:private class udpReceiveAndtcpSend extends Thread{ @Override public void run(){ // 设置缓冲区 byte[] data = new byte[1024]; try { InetAddress groupAddress = InetAddress.getByName("224.0.0.1"); ms = new MulticastSocket(6789); ms.joinGroup(groupAddress); } catch (Exception e) { e.printStackTrace(); } while(true){ try { dp = new DatagramPacket(data, data.length); if (ms != null) ms.receive(dp); } catch (Exception e) { e.printStackTrace(); } if(dp.getAddress() != null){ final String quest_ip = dp.getAddress().toString(); final String codeString = new String(data, 0, dp.getLength()); receive_label.post(new Runnable() { @Override public void run() { receive_label.append("收到来自: \n" + quest_ip.substring(1) + "\n" +"的udp请求\n"); receive_label.append("请求内容: " + codeString + "\n\n"); } }); try { final String target_ip = dp.getAddress().toString().substring(1); send_label.post(new Runnable() { @Override public void run() { send_label.append("发送tcp请求到: \n" + target_ip + "\n"); } }); socket = new Socket(target_ip, 8080); } catch (IOException e) { e.printStackTrace(); } finally { try { if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }
在点击发送按钮时会执行udp的多播。注意的是在主线程中不能直接进行网络操作,因此需要开启新的线程。case R.id.start: startBroadCast.setEnabled(false); stopBroadCast.setEnabled(true); /* 新开一个线程发送udp多播 */ new udpBroadCast("hello!").start(); break;
udpBroadCast的代码如下:private class udpBroadCast extends Thread { MulticastSocket sender = null; DatagramPacket dp = null; InetAddress group = null; byte[] data = new byte[1024]; public udpBroadCast(String dataString) { data = dataString.getBytes(); } @Override public void run() { try { sender = new MulticastSocket(); group = InetAddress.getByName("224.0.0.1"); dp = new DatagramPacket(data,data.length,group,6789); sender.send(dp); sender.close(); } catch(IOException e) { e.printStackTrace(); } } }
要注意端口的一致性。
以上就是整个项目的主要代码。功能比较基础,还是需要结合实际的开发做修改。完整代码请参考:项目代码
[android]一个关于UDP和TCP的项目实践(二)
最新推荐文章于 2024-05-18 10:52:51 发布