基於Android的TCP/IP除錯助手Demo
阿新 • • 發佈:2019-02-15
package com.loumeng.activity; import android.app.Activity; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.method.ScrollingMovementMethod; import android.util.Log; import android.view.View; import android.view.Window; import android.widget.AdapterView; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; import com.loumeng.Bluetooth.R; import com.loumeng.TCP.Data_syn; import com.loumeng.TCP.TCP_client; import com.loumeng.TCP.TCP_service; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.UnknownHostException; /** * Created by Administrator on 2017/1/12. */ public class TCPchat extends Activity { private static final String TAG_1 = "TCPChat"; //控制元件按鈕 private Button start; private Button stop; private Button clear_; private Button send; //複選按鈕控制元件 private CheckBox hex_show; private CheckBox auto_huang; private CheckBox hex_send; private CheckBox auto_send; //文字顯示控制元件 private TextView ip_mode; private TextView port_mode; private TextView de_state; //設定狀態 private TextView ip_show; //連線的物件IP 顯示 private TextView name_show; //連線的物件主機名號 顯示 private TextView re_count; //接收位元組數 private TextView se_count; //傳送位元組數 private TextView re_data_show; //接收位元組顯示 //編輯框控制元件 private EditText edit_ip; private EditText edit_port; private EditText edit_time; private EditText edit_data; //下拉控制元件 private Spinner link_mode; //連線模式 // private boolean exit; //網路連線模式選擇 public final static int MODE_TCP_SERVER=0; public final static int MODE_TCP_CLIENT=1; public final static int MODE_UDP=2; private int ch_mode=0; //TCP伺服器通訊模式下 private TCP_service tcp_service =null; private int ser_port; private boolean ser_islink=false; public final static int SERVER_STATE_CORRECT_READ=3; public final static int SERVER_STATE_CORRECT_WRITE=4; //正常通訊資訊 public final static int SERVER_STATE_ERROR=5; //發生錯誤異常資訊 public final static int SERVER_STATE_IOFO=6; //傳送SOCKET資訊 // TCP客戶端通訊模式下 private TCP_client tcp_client =null; private final static int CLIENT_STATE_CORRECT_READ=7; public final static int CLIENT_STATE_CORRECT_WRITE=8; //正常通訊資訊 public final static int CLIENT_STATE_ERROR=9; //發生錯誤異常資訊 public final static int CLIENT_STATE_IOFO=10; //傳送SOCKET資訊 private boolean client_islink =false; //複選狀態資訊 private boolean Hex_show =false; private boolean Auto_huang =false; private boolean Hex_send =false; private boolean Auto_send =false; //計數用 private int countin =0; private int countout=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.ly_tcpchat); SlidingMenuinit(); //側滑選單初始化 init(); link_mode.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { ch_mode = position; if (ch_mode == MODE_TCP_SERVER) { ip_mode.setText("本地 I P"); port_mode.setText("本地埠"); start.setText("啟動"); de_state.setText(""); ip_show.setHint("物件IP"); name_show.setHint("物件主機名"); clear(); } if (ch_mode == MODE_TCP_CLIENT) { ip_mode.setText("目的 I P"); port_mode.setText("目的埠"); start.setText("連線"); de_state.setText(""); ip_show.setHint("物件IP"); name_show.setHint("物件主機名"); clear(); } } @Override public void onNothingSelected(AdapterView<?> parent) { } }); edit_ip.setText(getLocalIpAddress()); //獲取本地IP地址顯示 edit_port.setText(8080+""); //設定預設埠號 start.setOnClickListener(startlistener); stop.setOnClickListener(stoplistener); send.setOnClickListener(sendlistener); clear_.setOnClickListener(clearlistener); hex_send.setOnCheckedChangeListener(listener); hex_show.setOnCheckedChangeListener(listener); auto_huang.setOnCheckedChangeListener(listener); auto_send.setOnCheckedChangeListener(listener); } //初始化控制元件函式 private void init() { link_mode= (Spinner) findViewById(R.id.ch_mode); ip_mode= (TextView) findViewById(R.id.ip_mode); port_mode= (TextView) findViewById(R.id.port_mode); start= (Button) findViewById(R.id.start); stop= (Button) findViewById(R.id.stop); clear_= (Button) findViewById(R.id.de_clear); send= (Button) findViewById(R.id.de_send); de_state= (TextView) findViewById(R.id.de_action); ip_show= (TextView) findViewById(R.id.de_ip); name_show= (TextView) findViewById(R.id.de_sport); re_count= (TextView) findViewById(R.id.receive_count); se_count= (TextView) findViewById(R.id.send_count); re_data_show= (TextView) findViewById(R.id.receive); re_data_show.setMovementMethod(ScrollingMovementMethod .getInstance());// 使TextView接收區可以滾動 edit_ip= (EditText) findViewById(R.id.ip_edit); edit_port= (EditText) findViewById(R.id.port_edit); edit_time= (EditText) findViewById(R.id.edi_auto); edit_data= (EditText) findViewById(R.id.send_data); hex_show= (CheckBox) findViewById(R.id.hex_show); auto_huang= (CheckBox) findViewById(R.id.autohuang); hex_send= (CheckBox) findViewById(R.id.hex_send); auto_send= (CheckBox) findViewById(R.id.auto_send); } private OnCheckedChangeListener listener =new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { switch (buttonView.getId()){ case R.id.hex_show: if (isChecked) { Toast.makeText(TCPchat.this, "16進位制顯示", Toast.LENGTH_SHORT).show(); Hex_show = true; } else Hex_show = false; break; case R.id.autohuang: if (isChecked) { Toast.makeText(TCPchat.this, "自動換行", Toast.LENGTH_SHORT).show(); Auto_huang = true; } else Auto_huang = false; break; case R.id.hex_send: if (isChecked) { Toast.makeText(TCPchat.this, "16進位制傳送", Toast.LENGTH_SHORT).show(); Hex_send = true; } else Hex_send = false; break; case R.id.auto_send: if (isChecked) { Toast.makeText(TCPchat.this, "16進位制傳送", Toast.LENGTH_SHORT).show(); Auto_send = true; } else Auto_send = false; break; } } }; private View.OnClickListener startlistener= new View.OnClickListener() { @Override public void onClick(View v) { if (ch_mode==MODE_TCP_SERVER){ if(tcp_service == null){ ser_port=Integer.valueOf(edit_port.getText().toString()); //獲取設定的埠號 預設8080 tcp_service =new TCP_service(ser_handler,ser_port); tcp_service.start(); de_state.setText("TCP伺服器模式 啟動"); stop.setEnabled(true); edit_ip.setEnabled(false); edit_port.setEnabled(false); } else{ Log.e(TAG_1, "斷開連線監聽 釋放資源"); de_state.setText("TCP伺服器模式 出錯"); } } if(ch_mode==MODE_TCP_CLIENT){ if(tcp_client == null) { tcp_client =new TCP_client(cli_handler); try { InetAddress ipAddress = InetAddress.getByName (edit_ip.getText().toString()); int port =Integer.valueOf(edit_port.getText().toString());//獲取埠號 tcp_client.setInetAddress(ipAddress); tcp_client.setPort(port); } catch (UnknownHostException e) { e.printStackTrace(); } edit_ip.setEnabled(false); edit_port.setEnabled(false); tcp_client.start(); } stop.setEnabled(true); } } }; private View.OnClickListener clearlistener=new View.OnClickListener() { @Override public void onClick(View v) { clear(); } }; private View.OnClickListener stoplistener= new View.OnClickListener() { @Override public void onClick(View v) { if (ch_mode==MODE_TCP_SERVER){ tcp_service.setis_start(false); if(tcp_service!=null) { tcp_service.close(); tcp_service=null; } de_state.setText("TCP伺服器模式 關閉"); Ip_clear(); edit_ip.setEnabled(true); edit_port.setEnabled(true); } if(ch_mode == MODE_TCP_CLIENT){ if(tcp_client != null){ tcp_client.close(); tcp_client=null; } Ip_clear(); edit_ip.setEnabled(true); edit_port.setEnabled(true); stop.setEnabled(false); } } }; //傳送響應函式 private View.OnClickListener sendlistener= new View.OnClickListener() { @Override public void onClick(View v) { if (ch_mode==MODE_TCP_SERVER){ if(ser_islink==true){ String message= edit_data.getText().toString().replaceAll(" ",""); if(message.equals("")){ Toast.makeText(TCPchat.this,"傳送內容不能為空", Toast.LENGTH_SHORT).show(); } sendmessage(message); }else{ Toast.makeText(TCPchat.this,"連線未建立", Toast.LENGTH_SHORT).show(); } } if (ch_mode==MODE_TCP_CLIENT){ if(client_islink==true){ String message= edit_data.getText().toString().replaceAll(" ",""); if(message.equals("")){ Toast.makeText(TCPchat.this,"傳送內容不能為空", Toast.LENGTH_SHORT).show(); } sendmessage(message); }else{ Toast.makeText(TCPchat.this,"連線未建立", Toast.LENGTH_SHORT).show(); } } } }; @Override protected void onDestroy(){ super.onDestroy(); if(tcp_service!=null) { tcp_service.setis_start(false); tcp_service.close(); tcp_service=null; } if(tcp_client != null){ tcp_client.close(); tcp_client=null; } } private void SlidingMenuinit() //側滑介面初始化函式,網上的列子很多,架包配置Android studio,網上有大量的教程
{ SlidingMenu menu = new SlidingMenu(this); menu.setMode(SlidingMenu.LEFT); // 設定觸控式螢幕幕的模式 menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); menu.setShadowWidthRes(R.dimen.shadow_width); menu.setShadowDrawable(R.drawable.shadow); // 設定滑動選單檢視的寬度 menu.setBehindOffsetRes(R.dimen.slidingmenu_offset); // 設定漸入漸出效果的值 menu.setFadeDegree(0.35f); //把滑動選單新增進所有的Activity中,可選值SLIDING_CONTENT , SLIDING_WINDOW menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT); //為側滑選單設定佈局 menu.setMenu(R.layout.ly_tcpchat_left); } private Handler ser_handler =new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what==SERVER_STATE_ERROR){ Toast.makeText(TCPchat.this,"連線異常" ,Toast.LENGTH_SHORT).show(); de_state.setText("TCP伺服器模式 連線異常"); ip_show.setHint("物件IP"); name_show.setHint("物件主機名"); ser_islink=false; } //傳送資料 if (msg.what==SERVER_STATE_CORRECT_WRITE){ Handler_send(msg); } //接收資料 if(msg.what==SERVER_STATE_CORRECT_READ){ Handler_receive(msg); } if(msg.what==SERVER_STATE_IOFO){ ser_islink=true; de_state.setText("TCP伺服器模式 建立連線"); stop.setEnabled(true); String[] strings= (String[]) msg.obj; ip_show.append(strings[0]+"\n"); name_show.append(strings[1]+"\n"); } } }; //客戶端通訊模式下 private Handler cli_handler =new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch( msg.what){ case CLIENT_STATE_ERROR : Toast.makeText(TCPchat.this,"連線異常" ,Toast.LENGTH_SHORT).show(); de_state.setText("TCP客戶端模式 連線異常"); ip_show.setHint("物件IP"); name_show.setHint("物件主機名"); client_islink=false; break; case CLIENT_STATE_IOFO : client_islink =true; de_state.setText("TCP客戶端模式 建立連線"); String[] strings= (String[]) msg.obj; ip_show.append(strings[0]+"\n"); name_show.append(strings[1]+"\n"); break; //接收資料 case CLIENT_STATE_CORRECT_READ : Handler_receive(msg); break; //傳送資料 case CLIENT_STATE_CORRECT_WRITE: Handler_send(msg); break; } } }; @Override public void onBackPressed() { exit(); } //獲取wifi本地IP和主機名 private String getLocalIpAddress() { WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); // 獲取32位整型IP地址 int ipAddress = wifiInfo.getIpAddress(); //返回整型地址轉換成“*.*.*.*”地址 return String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); } //傳送資料函式 public void sendmessage(String message){ if(Hex_send == true){ byte[] send = Data_syn.hexStr2Bytes(message); if(ch_mode==MODE_TCP_SERVER) { tcp_service.write(send); }else if (ch_mode==MODE_TCP_CLIENT){ tcp_client.sendmessage(send); } }else{ byte[] send = message.getBytes(); if(ch_mode==MODE_TCP_SERVER) { tcp_service.write(send); }else if (ch_mode==MODE_TCP_CLIENT){ tcp_client.sendmessage(send); } } } //頁面退出函式 public void exit(){ if(exit == true){ this.finish(); } exit = true; Toast.makeText(this,"再按一次,返回上一頁",Toast.LENGTH_SHORT).show(); } //定時返回函式 private Runnable runnable = new Runnable() { @Override public void run() { String message = edit_data.getText().toString(); sendmessage(message); } }; //清除函式 private void clear() { countin=0; countout=0; re_count.setText("0個"); se_count.setText("0個"); re_data_show.setText(""); } // 接收資料處理分析函式,通過handler從子執行緒回傳到主執行緒 private void Handler_receive(Message msg){ byte[] buffer= (byte[]) msg.obj; if (Hex_show == true) { String readMessage = " " + Data_syn.bytesToHexString(buffer, msg.arg1); re_data_show.append(readMessage); if(Auto_huang==true){ re_data_show.append("\n"); } countin += readMessage.length() / 2; // 接收計數 re_count.setText("" + countin+"個"); } else if (Hex_show == false) { String readMessage = null; try { readMessage = new String(buffer, 0, msg.arg1, "GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } re_data_show.append(readMessage); if(Auto_huang==true){ re_data_show.append("\n"); } countin += readMessage.length(); // 接收計數 re_count.setText("" + countin+"個"); } } //傳送資料處理分析函式,通過handler從子執行緒回傳主執行緒 private void Handler_send(Message msg){ byte[] writeBuf = (byte[]) msg.obj; if (Auto_send == true) { String s = edit_time.getText().toString(); long t = Long.parseLong(s); ser_handler.postDelayed(runnable, t); } else if (Auto_send == false) { ser_handler.removeCallbacks(runnable); } if (Hex_send == true) { String writeMessage = Data_syn.Bytes2HexString(writeBuf); countout += writeMessage.length() / 2; se_count.setText("" + countout+"個"); } else if (Hex_send == false) { String writeMessage = null; try { writeMessage = new String(writeBuf, "GBK"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } countout += writeMessage.length(); se_count.setText("" + countout+"個"); } } //目的地址和目的主機名清空函式 private void Ip_clear(){ ip_show.setText(""); name_show.setText(""); } }