基于Android的TCP/IP调试助手Demo


经过一段时间的Android开发学习,本着学习的心态,再网上找了一个资源,做了一个TCP/IP 的调试助手,主要涉及socket通信。最后,由于感觉一个手机界面太过难看,用了现在网上用的普遍的方法,导入SlidingMenu-master包,做了个手机侧滑界面。总之,类似一些电脑上的串口调试助手,有数据发送区和数据接收区,主要有TCP客户端和TCP服务端两种模式。

 程序大体流程:

    1.在侧滑界面,由用户选择把手机作为连接模式,有“TCP客户端模式”和“TCP服务器模式”两种模式选择;
    2.对应不同的模式,分配不同的功能
        a.服务器模式:界面信息显示本地IP,可自行设置端口号,点击开启服务器按钮,开启TCP_service连接线程,启动serversocket,进行监听,当有客户端socket连接时,开启连接线程,进行数据的交互。
       b.客户端模式:用户设置所要连接的服务器的IP地址和端口号,点击连接,开启连接线程,连接成功后,进行与木目标服务器的数据交互。
    3.本demo还对交互数据进行了处理,可分为十六进制显示和ascll显示。加了一些自动自动发送,自动换行等的功能。

  本项目所用的权限:

   由于用到WIFI连接,以及IP的地址获取,要配置相应的权限:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
上代码的讲解吧:
首先是客户端的连接线程:Tcp_Client
 
  
代码如下:
 
  
package com.loumeng.TCP;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;


/**
 * Created by Administrator on 2017/2/15.
 */
public class TCP_client extends Thread{
    private static final String TAG_1 = "TCPChat";
    private Handler mhandler;
    private Socket socket;
    private boolean isruning;
    public InputStream inputStream;
    public OutputStream outputStream;
    private InetAddress inetAddress;                             //IP地址
    private int port;                                            //端口号
    public static int  CLIENT_STATE_CORRECT_READ=7;
    public static int  CLIENT_STATE_CORRECT_WRITE=8;               //正常通信信息
    public static int  CLIENT_STATE_ERROR=9;                 //发生错误异常信息
    public static int  CLIENT_STATE_IOFO=10;                  //发送SOCKET信息
    public TCP_client(Handler mhandler) {
        this.mhandler=mhandler;       //传递handler对象用于与主线程的信息交互
        isruning=true;
    }

    public void setInetAddress(InetAddress inetAddress) {
        this.inetAddress = inetAddress;
    }
    public void setPort(int port) {
        this.port = port;
    }
    @Override
    public void run() {
   if(socket == null){
       try {
           Log.e(TAG_1,"启动连接线程");
           socket=new Socket(inetAddress,port);
           new Receive_Thread(socket).start();  //启动接收线程
           getadress();
       } catch (IOException e) {
           e.printStackTrace();
           senderror();
       }
   }
    }
    public void getadress()  //获取本地的IP地址和端口号
{
        String[] strings = new String[2];
        strings[0]=socket.getInetAddress().getHostAddress();
        strings[1]=socket.getInetAddress().getHostName();
        Message message = mhandler.obtainMessage(CLIENT_STATE_IOFO,-1,-1,strings);
        mhandler.sendMessage(message);
    }

  public  void close(){
      if (socket !=null){
          try {
              socket.close();
              socket=null;
              isruning=false;
          } catch (IOException e) {
          }
          }else if (socket ==null){
          Log.e(TAG_1, "未建立连接");
      }
  }
    class Receive_Thread extends Thread{
        private  Socket msocket;
   public Receive_Thread (Socket msocket){
      this.msocket =msocket;
    }
        @Override
        public void run() {
            try {
                while (isruning) {
                    inputStream = msocket.getInputStream();
                    while (inputStream.available()==0){
                    }
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    final byte[] buffer = new byte[1024];//创建接收缓冲区

                    final int len = inputStream.read(buffer);//数据读出来,并且数据的长度
                    mhandler.sendMessage(mhandler.
                            obtainMessage(CLIENT_STATE_CORRECT_READ,len,-1,buffer));
                }
            }catch (IOException e) {
                    e.printStackTrace();
                   senderror();
                }finally {
                if(msocket!=null){
                    try {
                        msocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                try {
                if(inputStream!=null){
                    inputStream.close();
                }
                if (outputStream!=null){
                    outputStream.close();
                }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Log.e(TAG_1,"关闭连接,释放资源");
            }
        }
    }
   public void sendmessage(byte[] message){
       try {
           outputStream =socket.getOutputStream();
           mhandler.sendMessage(mhandler.
                   obtainMessage(CLIENT_STATE_CORRECT_WRITE,-1,-1,message));
           outputStream.write(message);

       } catch (IOException e) {
               senderror();
       }
   }

    void senderror(){
        mhandler.sendMessage(mhandler.obtainMessage(CLIENT_STATE_ERROR));  //发送连接的错误
}
}


 接下来是服务器端的连接子线程 TCP_serveice.class 
  
 
  
 
  
 
  
 
 
代码如下:
package com.loumeng.TCP;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;


/**
 * Created by Administrator on 2017/2/13.
 */
public class TCP_service extends Thread{
    private static final String TAG_1 = "TCPChat";
   private Handler mhandler;
   private   ServerSocket serverSocket;
    public InputStream Ser_inputStream;
    public OutputStream Ser_outputStream;
    private Socket Ser_Socket;
    private  int mport;
    private boolean is_start =true;
    public static int  SERVER_STATE_CORRECT_READ=3;
    public static int  SERVER_STATE_CORRECT_WRITE=4;               //正常通信信息
    public static int  SERVER_STATE_ERROR=5;                 //发生错误异常信息
    public static int  SERVER_STATE_IOFO=6;                  //发送SOCKET信息
    public TCP_service(Handler mhandler,int mport){
     this.mhandler=mhandler;
        this.mport=mport;
     }
    @Override
    public void run() {
        super.run();
        try {
             serverSocket= new ServerSocket(mport);
        } catch (IOException e) {
            e.printStackTrace();
            send_Error();
        }
         try {
             while (is_start)
             {
              Log.e(TAG_1,"等待客户端连接 is_start="+ is_start);
                Ser_Socket=serverSocket.accept();                     //开启监听
                 if(Ser_Socket!=null){
             //启动接收线程
             Receive_Thread receive_Thread = new Receive_Thread(Ser_Socket);    //当有客户端连接时,开启数据接收的线程
             receive_Thread.start();
                 }
            } }catch (IOException e) {
            e.printStackTrace();
            send_Error();                                                //  发送错误
       }
    }
    class  Receive_Thread extends  Thread {
        private Socket socket = null;

        public Receive_Thread(Socket socket) {
            this.socket = socket;
            getAddress();
            try {
                Ser_inputStream = socket.getInputStream();
                Ser_outputStream = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
                send_Error();
            }
        }

        public void getAddress() {
            InetAddress inetAddress = socket.getInetAddress();
            String[] strings = new String[2];
            strings[0] = inetAddress.getHostAddress();
            strings[1] = inetAddress.getHostName();
            Message message = mhandler.obtainMessage(SERVER_STATE_IOFO, strings);
            mhandler.sendMessage(message);
        }

        @Override
        public void run() {
            super.run();
            while (is_start) {
                try {
                    while (Ser_inputStream.available() == 0) {
                    }
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    final byte[] buf = new byte[1024];
                    final int len = Ser_inputStream.read(buf);
                    Message message = mhandler.obtainMessage(SERVER_STATE_CORRECT_READ, len, 1, buf);
                    mhandler.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                    send_Error();
                }
            }
            try {
                if (Ser_inputStream != null)
                    Ser_inputStream.close();
                if (Ser_outputStream != null)
                    Ser_outputStream.close();
                if (socket != null) {
                    socket.close();
                    socket = null;
                }
                Log.e(TAG_1, "断开连接监听 释放资源");

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

    }
    public void close() {
        try {
            if (serverSocket != null)
                serverSocket.close();
            if (Ser_Socket != null)
                Ser_Socket.close();
            Log.e(TAG_1, "断开连接监听 关闭监听SOCKET");
         } catch (IOException e) {
            e.printStackTrace();
         }
    }
    //数据写入函数
    public void write(byte[] buffer){
        try {
            if (Ser_outputStream!=null){
            Ser_outputStream.write(buffer);
            Message er_message = mhandler.
                    obtainMessage(SERVER_STATE_CORRECT_WRITE,-1,-1,buffer);
            mhandler.sendMessage(er_message);
            }else{ send_Error();}
        } catch (IOException e) {
            e.printStackTrace();
            send_Error();
        }
    }
    public  void send_Error(){
        Message er_message = mhandler.obtainMessage(SERVER_STATE_ERROR);
        mhandler.sendMessage(er_message);
    }
    public void setis_start(boolean is_start) {
        this.is_start = is_start;
    }
}
主界面的主程序:TCP_chat.class,主要是对以上两个子线程的调用和对数据的交互和处理。
代码如下:
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("");
    }
}
代码比较多,本人也是新手,可能有部分代码不怎么科学合理,但总体经过测试可用,主要函数代码都有一定的注释,相信各位也看的懂得啦。
接下来是数据处理的代码,涉及十六进制和ascll数据的转化
代码如下:
package com.loumeng.TCP;
public class Data_syn {
    // 将字节数组转化为16进制字符串,确定长度
    public static String bytesToHexString(byte[] bytes, int a) {
        String result = "";
        for (int i = 0; i < a; i++) {
            String hexString = Integer.toHexString(bytes[i] & 0xFF);// 将高24位置0
            if (hexString.length() == 1) {
                hexString = '0' + hexString;
            }
            result += hexString.toUpperCase();
        }
        return result;
    }
    // 将字节数组转化为16进制字符串,不确定长度
    public static String Bytes2HexString(byte[] b) {
        String ret = "";
        for (int i =0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);// 将高24位置0
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase();
        }
        return ret;
    }
    // 将16进制字符串转化为字节数组
    public static byte[] hexStr2Bytes(String paramString) {
        int i = paramString.length() / 2;

        byte[] arrayOfByte = new byte[i];
        int j = 0;
        while (true) {
            if (j >= i)
                return arrayOfByte;
            int k = 1 + j * 2;
            int l = k + 1;
            arrayOfByte[j] = (byte) (0xFF & Integer.decode(
                    "0x" + paramString.substring(j * 2, k)
                            + paramString.substring(k, l)).intValue());
            ++j;
        }
    }

}



接下是一些布局代码,主要有两个布局,一个设置界面和主界面

  主界面布局 文件ly_tcpchat.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="1"
    android:background="#CDAA7D35">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:textColor="#000000"
            android:text="@string/link_"/>
        <TextView
            android:id="@+id/de_action"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#000000"
            android:textSize="15sp"
            android:hint="@string/de_state"/>
    </LinearLayout>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
         >
        <TextView
            android:id="@+id/de_ip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="15sp"
            android:hint="@string/d_ip"
            android:textColor="#1C1C1C"
            />
        <TextView
            android:id="@+id/de_sport"
            android:layout_alignParentRight="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="15sp"
            android:textColor="#1C1C1C"
            android:hint="@string/d_port"/>
    </RelativeLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/re_data"
            android:textSize="20sp"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/re_count"
            android:layout_marginLeft="100dp"
            android:textSize="15sp"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="@string/_0"
            android:id="@+id/receive_count"
            android:textSize="15sp"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.6"
        android:background="#EED5D2">
        <TextView
            android:id="@+id/receive"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="#EED5D2"
            android:textColor="#2F4F4F"
            android:textSize="20sp"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp"
            android:text="@string/se_data"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/send_count"
            android:layout_marginLeft="100dp"
            android:textSize="15sp"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="@string/_0"
            android:id="@+id/send_count"
            android:textSize="15sp"/>

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.4">
        <EditText
            android:id="@+id/send_data"
            android:layout_width="match_parent"
            android:layout_height="180dp"
            android:textSize="25sp"
            android:textColor="#2F4F4F"
            android:background="#EED5D2"/>
    </LinearLayout>
  <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:gravity="center_horizontal"
      android:weightSum="1">
      <Button
          android:id="@+id/de_clear"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_weight="0.4"
          android:layout_marginBottom="20dp"
          android:text="@string/de_clear"/>
      <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/de_send"
          android:layout_marginBottom="20dp"
          android:layout_marginLeft="5dp"
          android:layout_weight="0.4"
          android:text="@string/de_send"/>
  </LinearLayout>
</LinearLayout>


ly_tcpchat_left.xml 布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/b_kuan">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="@string/set"
        android:textSize="25sp"
        android:layout_gravity="center"
        android:textColor="#000000"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/li_mode"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="30dp"
             android:textSize="15sp"
            android:textColor="#2F4F4F"/>
        <Spinner
            android:id="@+id/ch_mode"
            android:layout_width="150dp"
            android:layout_height="30dp"
            android:entries="@array/mode"
            android:layout_gravity="center_horizontal"
            android:spinnerMode="dialog">
        </Spinner>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dp"
        >
        <TextView
            android:id="@+id/ip_mode"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/de_ip"
            android:layout_gravity="center_vertical"
            android:layout_marginLeft="30dp"
            android:textSize="15sp"
            android:textColor="#2F4F4F"/>
       <EditText
           android:id="@+id/ip_edit"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center_horizontal"
           android:textSize="15sp"
           android:textColor="#696969"
           android:layout_marginLeft="15dp"
           android:hint="@string/ip"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dp"
        >
        <TextView
            android:id="@+id/port_mode"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="30dp"
            android:layout_gravity="center_vertical"
            android:text="@string/de_poet"
            android:textSize="15sp"
            android:textColor="#2F4F4F"/>
        <EditText
            android:id="@+id/port_edit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:textSize="13sp"
            android:textColor="#696969"
            android:layout_marginLeft="15dp"
            android:hint="@string/port"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="1dp"
        android:gravity="center"
        >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/start"
            android:textSize="15sp"
            android:text="@string/start"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/stop"
            android:textSize="15sp"
            android:layout_marginLeft="5dp"
            android:enabled="false"
            android:text="@string/out"/>
    </LinearLayout>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:text="@string/re_set"
        android:textSize="25sp"
        android:layout_gravity="center"
        android:textColor="#000000"/>

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hex_show"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="20dp"
        android:textColor="#2F4F4F"
        android:id="@+id/hex_show"
        android:textSize="15sp"

        android:checked="false" />
    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/auto_huan"
        android:textSize="15sp"
        android:layout_marginTop="10dp"
        android:textColor="#2F4F4F"
        android:id="@+id/autohuang"
        android:layout_marginLeft="30dp" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="45dp"
        android:text="@string/send_set"
        android:textSize="25sp"
        android:layout_gravity="center"
        android:textColor="#000000"/>
    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hex_send"
        android:textSize="15sp"
        android:layout_marginTop="10dp"
        android:textColor="#2F4F4F"
        android:id="@+id/hex_send"
        android:layout_marginLeft="30dp"
        android:checked="false" />
    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/auto_send"
        android:textSize="15sp"
        android:layout_marginTop="1dp"
        android:textColor="#2F4F4F"
        android:id="@+id/auto_send"
        android:layout_marginLeft="30dp"/>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="45dp"
        android:textColor="#2F4F4F"
        android:textSize="15sp"
        android:text="@string/time"/>
    <EditText
        android:id="@+id/edi_auto"
        android:layout_width="50dp"
        android:layout_marginLeft="10dp"
        android:layout_height="match_parent"
        android:background="#ffffffff"
        android:ems="10"
        android:hint="@string/edtauto"
        android:inputType="number"
        android:textColor="#ff000000"
        android:textSize="18sp" />
</LinearLayout>
</LinearLayout>

项目Demo的效果截图如下:

第二个界面,侧滑界面


总结:

   这个项目总的来说是比较简单的,解释涉及Java socket的通信,不管是作为服务器或者客户端,都是socket在通信。侧滑界面的设置和使用,网上资料很多,这这里就不一一解释说明了。代码上去弄得比较繁琐,学习做的东西,还请各位请见谅,有什么意见和想法,欢迎留言,一起共同努力。

源码下载地址:http://download.csdn.net/detail/sinat_27064327/9809705


猜你喜欢

转载自blog.csdn.net/sinat_27064327/article/details/69950287