zoukankan      html  css  js  c++  java
  • 15.Android-实现TCP客户端,支持读写

    在上章14.Android-使用sendMessage线程之间通信我们学习了如何在线程之间发送数据.

    接下来我们便来学习如何通过socket读写TCP.

    需要注意的是socket必须写在子线程中,不能在ui主线程中直接使用,所以我们这里创建了两个class:

    MainActivity(主界面)、TcpThread(获取socket接收的数据)

    由于代码有注释了,所以就不解释了.

    1.gif效果如下

    2.activity_main.xml如下所示:

    <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"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".MainActivity" >
    
        
        <EditText 
            android:id="@+id/et_text"
            android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:layout_alignParentTop="true"
            android:hint="请填入要发送的内容"
            />
        
         <Button 
            android:id="@+id/btn_send"
            android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_alignParentRight="true"
               android:layout_below="@+id/et_text"
            android:text="发送"
            />
         
         <TextView 
             android:id="@+id/tv_recv"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_below="@+id/btn_send"
             android:minLines="20"
             android:hint="接收的内容"
             />
    </RelativeLayout>

    3.MainActivity.java如下所示

    package com.example.tcpdemo;
    
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.app.Activity;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
    
        TcpThread mt;
        
        TextView tv_recv;
        EditText et_text;        //要发送的内容
        Button    btn_send;
        
        //定义一个handler
        public Handler mHandler = new Handler() {
            public void handleMessage(Message msg) {
                //打印服务器端发来的消息
                System.out.println("read:"+msg.obj.toString());
                tv_recv.append(msg.obj.toString()+"
    ");
            };
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            tv_recv =  (TextView)findViewById(R.id.tv_recv);
            et_text =  (EditText)findViewById(R.id.et_text);
            
            
            mt = new TcpThread();
            mt.setHandler(mHandler);    //设置handler
            mt.setIp("10.10.10.104");   //设置服务器地址
            mt.start();                    //启动线程
            
            
            btn_send =  (Button)findViewById(R.id.btn_send);
            
            btn_send.setOnClickListener(new OnClickListener() {
                
                //向服务器端发送数据
                public void onClick(View v) {
                    
                    if(!mt.write(et_text.getText().toString()))
                    {
                        Toast.makeText(getApplicationContext(), "发送失败", Toast.LENGTH_SHORT).show();
                        
                    }
                }
            });
        }
    }

    4.TcpThread.java如下所示

    package com.example.tcpdemo;
    
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import android.os.Handler;
    import android.os.Message;
    
    public class TcpThread extends Thread {
        
            
            Handler mHandler=null; 
            Socket socket = null;
            String ip = null;
            OutputStream outputStream = null;        //输出流
            InputStream inputStream=null;            //接收流
            //获取另一个线程的Handler
            public void setHandler( Handler handler){
                mHandler = handler;
            }
            
            //设置服务器IP
            public void setIp(String ip){
                this.ip = ip;
            }
                    
            public void run(){
               
              try {
                        socket = new Socket(ip, 8080);        //访问指定的ip地址:8080

    // 1 UnknownHostException:如果无法识别主机的名字或IP地址,就会抛出这种异常。
    // 2 ConnectException:如果没有服务器进程监听指定的端口,或者服务器进程拒绝连接,就会抛出这种异常。
    // 3 SocketTimeoutException:如果等待连接超时,就会抛出这种异常。
    // 4 BindException:如果无法把Socket对象与指定的本地IP地址或端口绑定,就会抛出这种异常

    
                    } catch (UnknownHostException e) { 
                        e.printStackTrace();
                    } catch (IOException e) { 
                        e.printStackTrace();
                    }
                    
             
               //获取输出流
                try {
                    outputStream = socket.getOutputStream();
                    
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }    
                try{
                    while (true)         //读取服务器端发送来的数据
                    {
                        final byte[] buffer = new byte[1024];//创建接收缓冲区
                        inputStream = socket.getInputStream();
                        final int len = inputStream.read(buffer);//数据读出来,并且返回数据的长度
                        if(len>0)
                        {
                             Message msg = mHandler.obtainMessage(); 
                             //设置发送的内容
                             msg.obj = new String(buffer,0,len); 
                             mHandler.sendMessage(msg);  
                        }
                        
                    }
                }
                catch (IOException e) {
                    
                }
                
            }
            
            //向服务器端写入数据
            public boolean write(String text){
                
                boolean ret = true;
                try {
                    outputStream.write(text.toString().getBytes());
                } catch (IOException e) { 
                    ret = false;
                    e.printStackTrace();
                }
                return ret;
            }
    }

     注意1:

    使用inputStream.read(buffer)的时候如果读取不到数据,会进入阻塞状态,直到有数据来了,才会退出执行下个语句.如果想不使用阻塞的话,可以通过if(inputStream.available()>0)来判断是否有数据来了.再读取即可

  • 相关阅读:
    Asp.Net细节性问题精萃(转)
    开发OFFICE插件总结(转)
    校内网开心网数据同步引发的讨论(转)
    C++指针探讨 (三) 成员函数指针 (转)
    C++指针探讨 (二) 函数指针 (转)
    【原创】编程获取PE文件信息的方法(转)
    为.net开发者提供的一份关于存储过程的评论(转)
    C++指针探讨 (一)数据指针 (转)
    如何批量修改PPT字体、大小、颜色(转)
    搜索引擎里的爱人(转)
  • 原文地址:https://www.cnblogs.com/lifexy/p/12304497.html
Copyright © 2011-2022 走看看