基于TCP的安卓客户端开发详细流程

基于TCP的安卓客户端开发详细流程

一.权限申明

    <!--允许应用程序改变网络状态-->
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>

    <!--允许应用程序改变WIFI连接状态-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

    <!--允许应用程序访问有关的网络信息-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <!--允许应用程序访问WIFI网卡的网络信息-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

    <!--允许应用程序完全使用网络-->
    <uses-permission android:name="android.permission.INTERNET"/>

二.布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    >
    <TextView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:layout_marginTop="12dp"
        android:layout_gravity="center"
        android:text="IP:"
        android:textSize="20dp"/>
    <EditText
        android:id="@+id/IPEditText"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:gravity="center"
        android:layout_weight="4"
        android:text="223.3.200.4"
        android:textSize="20dp"
        />
    <TextView
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2"
        android:layout_marginTop="12dp"
        android:layout_gravity="center"
        android:text="Port:"
        android:textSize="20dp"/>
    <EditText
        android:id="@+id/PortEditText"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:gravity="center"
        android:layout_weight="2"
        android:text="8086"
        android:textSize="20dp"
        />
    <Button
        android:id="@+id/ConnectButton"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="连接"/>

</LinearLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"

    >
    <EditText
        android:id="@+id/MessagetoSendEditText"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"
        android:text="Data from Client"/>
    <Button
        android:id="@+id/SendButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="发送"/>
</LinearLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    >
    <TextView
        android:id="@+id/DisplayTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:hint="Display area:"
        android:textSize="20dp"/>
</LinearLayout>

三.具体代码实现

package com.example.john.androidsockettest_client;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

public class MainActivity extends AppCompatActivity {

//Handler中的消息类型
public static final int DEBUG = 0x00;
public static final int RECEIVEDATAFROMSERVER = 0x01;
public static final int SENDDATATOSERVER = 0x02;
//线程
Socket socket = null;               //成功建立一次连接后获得的套接字
ConnectThread connectThread;       //当run方法执行完后,线程就会退出,故不需要主动关闭
SendThread sendThread;             //发送线程,由send按键触发
ReceiveThread receiveThread;       //接收线程,连接成功后一直运行
//待发送的消息
public String messagetoSend = "";
//控件
TextView displayTextView;             //显示接收、发送的数据及Debug信息
Button sendButton;                    //发送按钮,点击触发发送线程
Button connectButton;                //连接按钮,点击触发连接线程
EditText messagetoSendEditText;
EditText iPEditText;
EditText portEditText;

public Handler myHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (msg.what == RECEIVEDATAFROMSERVER) {
            Bundle bundle = msg.getData();
            displayTextView.append("Server:"+bundle.getString("string1")+"\n");
        }
        else if (msg.what == DEBUG) {
            Bundle bundle = msg.getData();
            displayTextView.append("Debug:"+bundle.getString("string1")+"\n");
        }
        else if (msg.what == SENDDATATOSERVER) {
            Bundle bundle = msg.getData();
            displayTextView.append("Client:"+bundle.getString("string1")+"\n");
        }
    }

};
//子线程更新UI
public void SendMessagetoHandler(final int messageType , String string1toHandler){
    Message msg = new Message();
    msg.what = messageType;    //消息类型
    Bundle bundle = new Bundle();
    bundle.clear();
    bundle.putString("string1", string1toHandler); //向bundle中添加字符串
    msg.setData(bundle);
    myHandler.sendMessage(msg);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    displayTextView = (TextView) findViewById(R.id.DisplayTextView);
    sendButton = (Button) findViewById(R.id.SendButton);
    messagetoSendEditText = (EditText) findViewById(R.id.MessagetoSendEditText);
    iPEditText = (EditText)findViewById(R.id.IPEditText);
    portEditText = (EditText)findViewById(R.id.PortEditText);
    connectButton = (Button)findViewById(R.id.ConnectButton);

    connectButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            connectThread= new ConnectThread();
            connectThread.start();
        }
    });
    sendButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            messagetoSend = messagetoSendEditText.getText().toString();
            //使用连接成功后得到的socket构造发送线程,每点击一次send按钮触发一次发送线程
            sendThread = new SendThread(socket);
            sendThread.start();
        }
    });
}

//********  连接线程  **********
class ConnectThread extends Thread{
    @Override
    public void run() {
        try{
            //连接服务器 并设置连接超时为1秒
            socket = new Socket();
            socket.connect(new InetSocketAddress(iPEditText.getText().toString(),
                    Integer.parseInt(portEditText.getText().toString())), 1000);
        }catch (SocketTimeoutException aa) {
            //更新UI:连接失败
            SendMessagetoHandler(DEBUG,"服务器连接失败!");
            return;     //直接返回
        } catch (IOException e) {
            e.printStackTrace();

        }
        //更新UI:连接成功
        SendMessagetoHandler(DEBUG,"服务器连接成功!");

        //打开接收线程
        receiveThread = new ReceiveThread(socket);
        receiveThread.start();
    }
}
//********  发送线程  **********
class SendThread extends Thread{
    private Socket mSocket;
    //发送线程的构造函数,由连接线程传入套接字
    public SendThread(Socket socket) {mSocket = socket;}

    @Override
    public void run() {
        try{
            OutputStream outputStream = mSocket.getOutputStream();
            //向服务器发送信息
            outputStream.write(messagetoSend.getBytes("gbk"));
            outputStream.flush();
            //更新UI:显示发送出的数据
            SendMessagetoHandler(SENDDATATOSERVER,messagetoSend);
        }catch (IOException e) {
            e.printStackTrace();
            //更新UI:显示发送错误信息
            SendMessagetoHandler(DEBUG,"发送失败!");
            return;
        }
    }
}

//********  接收线程  **********
class ReceiveThread extends Thread{

    private Socket mSocket;
    //接收线程的构造函数,由连接线程传入套接字
    public ReceiveThread(Socket socket){mSocket = socket;}

    @Override
    public void run() {
        while(true){               //连接成功后将一直运行
            try {
                BufferedReader bufferedReader;
                String line = null;
                String readBuffer="";
                bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
                while ((line = bufferedReader.readLine()) != null) {
                    readBuffer = line + readBuffer;
                    SendMessagetoHandler(RECEIVEDATAFROMSERVER,readBuffer);
                    readBuffer = "";
                }
                bufferedReader.close();
            }catch (IOException e) {
                e.printStackTrace();
                //更新UI:显示发送错误信息
                SendMessagetoHandler(DEBUG,"接收失败!");
                return;
            }
        }
    }
  }
}

四、运行效果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值