√ Socket Server Testing sample code(接收byte)

接收String之sample code:[Android] [Studio] Socket Server接收測試程式—String

點選啟動之Button後,即開啟Server,與接收字串之程式僅一小段不同,使用Log輸出讀取之字元

 ⌲Mainactivity.java

package com.xin.socket6;

/*
* by Xin.
* 2018/05/04 Testing OK  */

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainActivity extends Activity {

    private static final int PORT = 9999;
    private List<Socket> mList = new ArrayList<Socket>();
    private volatile ServerSocket server=null;
    private ExecutorService mExecutorService = null; //線程
    private String hostip; //本機IP
    private TextView mText1;
    private TextView mText2;
    private Button mBut1=null;
    private Handler myHandler=null;
    private volatile boolean flag= true;//线程标志位
    private Handler handler = new Handler();
    String s ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        hostip = getLocalIpAddress();  //獲取本機IP
        mText1=(TextView) findViewById(R.id.textView1);
        mText1.setText(hostip);
        mText1.setEnabled(false);

        mText2=(TextView) findViewById(R.id.textView2);

        mBut1=(Button) findViewById(R.id.but1);
        mBut1.setOnClickListener(new Button1ClickListener());
        //取得非UI線程傳來的msg,以改變介面
        myHandler =new Handler(){
            @SuppressLint("HandlerLeak")
            public void handleMessage(Message msg){
                if(msg.what==0x1234){
                    mText2.append("\n" + msg.obj.toString());
                }
            }
        };

    }
    //對button1的監聽事件
    private final class Button1ClickListener implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            //如果是「啟動」,證明服務器是關閉狀態,可以開啟服務器
            if(mBut1.getText().toString().equals("啟動")){
                ServerThread serverThread=new ServerThread();
                flag=true;
                serverThread.start();
                mBut1.setText("關閉");
                mText1.setText(getLocalIpAddress());
                //show IP address
                 Toast toast = Toast.makeText(MainActivity.this, "IP address: "+getLocalIpAddress(), Toast.LENGTH_LONG);
                 toast.show();
            }else{
                try {
                    flag=false;
                    server.close();
                    for(int p=0;p<mList.size();p++){
                        Socket s=mList.get(p);
                        s.close();
                    }
                    mExecutorService.shutdownNow();
                    mBut1.setText("啟動");
                    mText1.setText("Not Connect");
                    Log.v("Socket-status","服務器已關閉");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //Server端的主線程
    class ServerThread extends Thread {
        public void run() {
            try {
                server = new ServerSocket(PORT);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            mExecutorService = Executors.newCachedThreadPool();  //創建一個線程
            Socket client = null;
            while(flag) {
                try {
                    Log.v("test", String.valueOf(flag));
                    client = server.accept();
                    handler.post(new Runnable() {
                        public void run() {
                            mText1.setText("Connected.");
                        }
                    });
                    try {
                        handler.post(new Runnable() {
                            public void run() {
                                mText2.setText(s);  //post message on the textView
                            }
                        });
                    } catch (Exception e) {
                        handler.post(new Runnable() {
                            public void run() {
                                mText2.setText(s);
                            }
                        });
                    }
                    //把客户端放入客户端集合中
                    mList.add(client);
                    mExecutorService.execute(new Service(client)); //啟動一個新的線程來處理連接
                }catch ( IOException e) {
                    e.printStackTrace();
                    handler.post(new Runnable() {
                        public void run() {
                            mText2.setText("disConncet");
                        }
                    });
                }
            }
        }
    }
    //獲取本地IP
    @SuppressLint("LongLogTag")
    public static String getLocalIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf
                        .getInetAddresses(); enumIpAddr.hasMoreElements();) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress()) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
        } catch (SocketException ex) {
            Log.e("WifiPreference IpAddress", ex.toString());
        }
        return null;
    }
    //處理與client對話的線程
    class Service implements Runnable {
        private volatile boolean kk=true;
        private Socket socket;
        private BufferedReader in = null;
        private String msg = "";

        public Service(Socket socket) {
            this.socket = socket;   //reada6
            try {
                in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
                msg="OK";   //reada8
                this.sendmsg(msg);  //reada9

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void run() {
            while(kk) {
                try {
                    int size = input.read(tmpData); // size 是讀取到的字節數,tmpData[]即為接收到之byte array
      ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​ ​​​​​​​​​​Log.v("Socket-size", String.valueOf(size));
 ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​ ​​​​​​​if(size == -1) {
                       mList.remove(socket);
                       break;
                    }
                    else {
                        for (int i = 0; i < size; i++) {
                            Data[i] = byteToString(tmpData[i]);  //將接收到之byte轉為string,可以此陣列去做判斷
                            Log.v("Socket-data",Data[i]);
                        }
                        if (Data[8].equals("ED")) { //判斷之範例,因爲String array,故使用equals
                            Log.v("Socket-tmp","Data");
                        }
                    }
                } catch (IOException e) {
                    System.out.println("close");
                    kk=false;
                    e.printStackTrace();
                }
            }
        }
        //向客戶端發送訊息
        public void sendmsg(String msg) {
            System.out.println(msg);
            PrintWriter pout = null;
            try {
                pout = new PrintWriter(new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())),true);
                pout.println(msg);
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //byte轉換,輸出String,避免java轉換為string或int時出現負號,導致判斷錯誤
    public static long byteTointstring(byte b){
        return(Long.parseLong( byteToString(b), 16));
    }

    public static String byteToString(byte b) {
        byte high, low;
        byte maskHigh = (byte)0xf0;
        byte maskLow = 0x0f;

        high = (byte)((b & maskHigh) >> 4);
        low = (byte)(b & maskLow);

        StringBuffer buf = new StringBuffer();
        buf.append(findHex(high));
        buf.append(findHex(low));

        return buf.toString();
    }

    private static char findHex(byte b) {
        int t = new Byte(b).intValue();
        t = t < 0 ? t + 16 : t;
  
        if ((0 <= t) &&(t <= 9)) {
            return (char)(t + '0');
        }
  
        return (char)(t-10+'A');
    }
    public byte[] returndata() {
        return tmpData;
    }
}

 ⌲Layout-activity_main

<RelativeLayout 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"
    tools:context=".MainActivity" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <Button
                android:id="@+id/but1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:layout_alignBottom="@+id/textView1"
                android:layout_alignParentRight="true"
                android:text="啟動" />

            <TextView
                android:id="@+id/textView2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:layout_alignLeft="@+id/textView1"
                android:layout_below="@+id/textView1"
                android:text="Not Connect" />

            <TextView
                android:id="@+id/textView1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:text="IP" />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

 ⌲Manifest(增加權限,否則會崩潰)

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

 

 

文章標籤
創作者介紹
創作者 May 的頭像
May

Walking

May 發表在 痞客邦 留言(0) 人氣()