[android]一个关于UDP和TCP的项目实践(二)

    在上一篇[android]一个关于UDP和TCP的项目实践(一)中已经交代了项目逻辑和基本知识点,这篇解释代码。
    首先需要加上如下权限:
  <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"/>
    注意udp广播,和udp广播监听需要绑定同一个端口。
    测试机的版本为4.4。
    UI设计的很简单,三个功能按钮分别为发送广播、停止发送广播以及清除Textview里的内容。按钮下面的两个TextView分别显
示收到的udp请求和tcp请求以及发送的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>
    MainActivity中开启两个线程,分别用来接收tcp连接和接收udp多播并发送tcp连接:
  /* 开一个线程接收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();
            }
        }
    }

要注意端口的一致性。
    以上就是整个项目的主要代码。功能比较基础,还是需要结合实际的开发做修改。
    完整代码请参考:项目代码
    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值