转自:http://www.cnblogs.com/lknlfy/archive/2012/03/04/2379628.html

一、概述

关于Socket编程的基本方法在基础篇里已经讲过,今天把它给完善了。加入了多线程,这样UI线程就不会被阻塞;实现了客户端和服务器的双向通信,只要客户端发起了连接并成功连接后那么两者就可以随意进行通信了。

二、实现

在之前的工程基础上进行修改就可以了。

MyClient工程的main.xml文件不用修改,只需要修改MyClientActivity.java文件,主要是定义了一个继承自 Thread类的用于接收数据的类,覆写了其中的run()方法,在这个函数里面接收数据,接收到数据后就通过Handler发送消息,收到消息后在UI 线程里更新接收到的数据。完整的内容如下:

package com.nan.client;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;public class MyClientActivity extends Activity
{private EditText mEditText = null;private Button connectButton = null;private Button sendButton = null;private TextView mTextView = null;private Socket clientSocket = null;private OutputStream outStream = null;private Handler mHandler = null;private ReceiveThread mReceiveThread = null;private boolean stop = true;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mEditText = (EditText)this.findViewById(R.id.edittext);mTextView = (TextView)this.findViewById(R.id.retextview);connectButton = (Button)this.findViewById(R.id.connectbutton);sendButton = (Button)this.findViewById(R.id.sendbutton);sendButton.setEnabled(false);      //连接按钮监听connectButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubtry {//实例化对象并连接到服务器clientSocket = new Socket("113.114.170.246",8888);} catch (UnknownHostException e) {// TODO Auto-generated catch block
                    e.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch block
                    e.printStackTrace();}displayToast("连接成功!");                        //连接按钮使能connectButton.setEnabled(false);//发送按钮使能sendButton.setEnabled(true);mReceiveThread = new ReceiveThread(clientSocket);stop = false;//开启线程
                mReceiveThread.start();}});//发送数据按钮监听sendButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubbyte[] msgBuffer = null;//获得EditTex的内容String text = mEditText.getText().toString();try {//字符编码转换msgBuffer = text.getBytes("GB2312");} catch (UnsupportedEncodingException e1) {// TODO Auto-generated catch block
                    e1.printStackTrace();}try {//获得Socket的输出流outStream = clientSocket.getOutputStream();} catch (IOException e) {// TODO Auto-generated catch block
                    e.printStackTrace();}                                                    try {//发送数据
                    outStream.write(msgBuffer);} catch (IOException e) {// TODO Auto-generated catch block
                    e.printStackTrace();}//清空内容mEditText.setText("");displayToast("发送成功!");}});//消息处理mHandler = new Handler(){@Overridepublic void handleMessage(Message msg){//显示接收到的内容
                mTextView.setText((msg.obj).toString());}};}//显示Toast函数private void displayToast(String s){Toast.makeText(this, s, Toast.LENGTH_SHORT).show();}private class ReceiveThread extends Thread{private InputStream inStream = null;private byte[] buf;  private String str = null;ReceiveThread(Socket s){try {//获得输入流this.inStream = s.getInputStream();} catch (IOException e) {// TODO Auto-generated catch block
                e.printStackTrace();}}      @Overridepublic void run(){while(!stop){this.buf = new byte[512];try {//读取输入数据(阻塞)this.inStream.read(this.buf);} catch (IOException e) {// TODO Auto-generated catch block
                    e.printStackTrace();} //字符编码转换try {this.str = new String(this.buf, "GB2312").trim();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch block
                    e.printStackTrace();}Message msg = new Message();msg.obj = this.str;//发送消息
                mHandler.sendMessage(msg);}}}@Overridepublic void onDestroy(){super.onDestroy();if(mReceiveThread != null){stop = true;mReceiveThread.interrupt();}}}

对于MyServer工程,改动比较大,首先是main.xml文件,在里面添加了两个TextView,一个用于显示客户端的IP,一个用于显示接收到的内容,一个用于发送数据的Button,还有一个EditText,完整的main.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><TextView android:id="@+id/iptextview"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textSize="20dip"android:gravity="center_horizontal"/><EditText android:id="@+id/sedittext"android:layout_width="fill_parent"android:layout_height="wrap_content"android:hint="请输入要发送的内容"/><Button android:id="@+id/sendbutton"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="发送"/><TextViewandroid:id="@+id/textview"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textSize="15dip"/></LinearLayout>

接着,修改MyServerActivity.java文件,定义了两个Thread子类,一个用于监听客户端的连接,一个用于接收数据,其他地方与MyClientActivity.java差不多。完整的内容如下:

package com.nan.server;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;public class MyServerActivity extends Activity
{private TextView ipTextView = null;private EditText mEditText = null;private Button sendButton = null;private TextView mTextView = null;private OutputStream outStream = null;private Socket clientSocket = null;private ServerSocket mServerSocket = null;private Handler mHandler = null;private AcceptThread mAcceptThread = null;private ReceiveThread mReceiveThread = null;private boolean stop = true;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);ipTextView = (TextView)this.findViewById(R.id.iptextview);mEditText = (EditText)this.findViewById(R.id.sedittext);sendButton = (Button)this.findViewById(R.id.sendbutton);sendButton.setEnabled(false);mTextView = (TextView)this.findViewById(R.id.textview);//发送数据按钮监听sendButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubbyte[] msgBuffer = null;//获得EditTex的内容String text = mEditText.getText().toString();try {//字符编码转换msgBuffer = text.getBytes("GB2312");} catch (UnsupportedEncodingException e1) {// TODO Auto-generated catch block
                    e1.printStackTrace();}try {//获得Socket的输出流outStream = clientSocket.getOutputStream();} catch (IOException e) {// TODO Auto-generated catch block
                    e.printStackTrace();}                                                    try {//发送数据
                    outStream.write(msgBuffer);} catch (IOException e) {// TODO Auto-generated catch block
                    e.printStackTrace();}//清空内容mEditText.setText("");displayToast("发送成功!");}});//消息处理mHandler = new Handler(){@Overridepublic void handleMessage(Message msg){switch(msg.what){case 0:{//显示客户端IP
                        ipTextView.setText((msg.obj).toString());//使能发送按钮sendButton.setEnabled(true);break;}case 1:{//显示接收到的数据
                        mTextView.setText((msg.obj).toString());break;}                 }                                           }};mAcceptThread = new AcceptThread();//开启监听线程
        mAcceptThread.start();}//显示Toast函数private void displayToast(String s){Toast.makeText(this, s, Toast.LENGTH_SHORT).show();}private class AcceptThread extends Thread{@Overridepublic void run(){try {//实例化ServerSocket对象并设置端口号为8888mServerSocket = new ServerSocket(8888);} catch (IOException e) {// TODO Auto-generated catch block
                e.printStackTrace();}try {//等待客户端的连接(阻塞)clientSocket = mServerSocket.accept();} catch (IOException e) {// TODO Auto-generated catch block
                e.printStackTrace();}mReceiveThread = new ReceiveThread(clientSocket);stop = false;//开启接收线程
            mReceiveThread.start();Message msg = new Message();msg.what = 0;//获取客户端IPmsg.obj = clientSocket.getInetAddress().getHostAddress();//发送消息
            mHandler.sendMessage(msg);}}private class ReceiveThread extends Thread{private InputStream mInputStream = null;private byte[] buf ;  private String str = null;ReceiveThread(Socket s){try {//获得输入流this.mInputStream = s.getInputStream();} catch (IOException e) {// TODO Auto-generated catch block
                e.printStackTrace();}}@Overridepublic void run(){while(!stop){this.buf = new byte[512];//读取输入的数据(阻塞读)try {this.mInputStream.read(buf);} catch (IOException e1) {// TODO Auto-generated catch block
                    e1.printStackTrace();}//字符编码转换try {this.str = new String(this.buf, "GB2312").trim();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch block
                    e.printStackTrace();}Message msg = new Message();msg.what = 1;        msg.obj = this.str;//发送消息
                mHandler.sendMessage(msg);}}}@Overridepublic void onDestroy(){super.onDestroy();if(mReceiveThread != null){stop = true;mReceiveThread.interrupt();}}}

两个工程都修改好了,同样,在模拟器上运行客户端:

在真机上运行服务器端:

接着,点击客户端的“连接”按钮,看到“连接成功”提示后输入一些内容再点击“发送”按钮,此时客户端显示:

服务器端显示:

接下来两边都可以随意发送数据了。

转载于:https://www.cnblogs.com/lance-ehf/p/4526980.html

Android应用开发提高篇(4)-----Socket编程(多线程、双向通信)(转载)相关推荐

  1. Android应用开发提高篇(4)-----Socket编程(多线程、双向通信)

    一.概述 关于Socket编程的基本方法在基础篇里已经讲过,今天把它给完善了.加入了多线程,这样UI线程就不会被阻塞:实现了客户端和服务器的双向通信,只要客户端发起了连接并成功连接后那么两者就可以随意 ...

  2. Android应用开发提高篇(2)-----文本朗读TTS(TextToSpeech)

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/26/2368696.html 一.概述 TextToSpeech,就是将文本内容转换成语音,在其 ...

  3. Android NFC开发-理论篇

    Android NFC开发-理论篇 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/CSDN_GYG/article/details/72884849 ...

  4. android 串口开发第二篇:利用jni实现android和串口通信

    一:串口通信简介 由于串口开发涉及到jni,所以开发环境需要支持ndk开发,如果未配置ndk配置的朋友,或者对jni不熟悉的朋友,请查看上一篇文章,android 串口开发第一篇:搭建ndk开发环境以 ...

  5. Android应用开发提高系列(5)——Android动态加载(下)——加载已安装APK中的类和资源...

    前言  Android动态加载(下)--加载已安装APK中的类和资源. 声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯伯: http://ov ...

  6. Android App开发基础篇—数据存储(SQLite数据库)

    Android App开发基础篇-数据存储(SQLite数据库) 前言:Android中提供了对SQLite数据库的支持.开发人员可以在应用中创建和操作自己的数据库来存储数据,并对数据进行操作. 一. ...

  7. Android应用开发基础篇(12)-----Socket通信(转载)

    转自:http://www.devdiv.com/android_socket_-blog-258060-10594.html 一.概述 网络通信无论在手机还是其他设备上都应用得非常广泛,因此掌握网络 ...

  8. Android UI开发第四十一篇——墨迹天气3.0引导界面及动画实现

    周末升级了墨迹天气,看着引导界面做的不错,模仿一下,可能与原作者的代码实现不一样,但是实现的效果还是差不多的.先分享一篇以前的文章,android动画的基础知识,<Android UI开发第十二 ...

  9. Android系统开发-入门篇

    参见:[视频教程] 写给应用开发的 Android Framework 教程--玩转 AOSP 篇之 Android 系统开发工具推荐 - 掘金 前置条件: android系统源码位于 linux 服 ...

最新文章

  1. 吴恩达机器学习笔记-梯度下降
  2. 使用LVS(Linux Virtual Server)在Linux上搭建负载均衡的集群服务
  3. 常识:佛前三炷香是什么意思
  4. java基础(网络编程---IP、端口、URL)
  5. 【转】Dynamics 365中配置和使用文件夹级别的跟踪(folder-level tracking)
  6. NOI提高级:排序算法
  7. Python学习笔记(三)Python安装及设置环境变量
  8. 电镜的成像原理-冷冻电镜成像技术1
  9. oracle快速解析,教你用Oracle解析函数快速检查序列间隙
  10. 机器人matlab仿真步骤,MATLAB机器人仿真程序.doc
  11. opencv python 人脸识别 相似度_如何使用OpenCV3直方图方法进行人脸相似度对比
  12. 【微信小程序】数据绑定
  13. 计算机收不到打印机,打印机接收不到任务,如何添加打印机
  14. 老哥们着急求助一下:报错ORA-39083,ORA-00001
  15. 微型计算机噪声要求国标,中国噪声标准(GB noise standards)
  16. 荣耀A55高调上市只为孤独求败?
  17. 康托尔点集matlab实数,仿照科赫曲线程序 , 按照课件上的算法写出康托尔点集 – MATLAB中文论坛...
  18. ORACLE百例试炼五
  19. 基于JavaEye-API实现的Gerry-聊天QQ版v2.0
  20. Java生成Excel文件并响应给页面

热门文章

  1. python网站开发实例-【9】Python接口开发:flask Demo实例
  2. python在excel中的应用-python怎样在excel中应用?
  3. 大学python用什么教材-最好的Python入门教材是哪本?
  4. excel调用python编程-如何在excel中调用python脚本
  5. python初学者视频-python从入门到精通视频(全60集)
  6. 自学python还是报班-没有基础想学python为什么一定要报班?
  7. python3语法错误-使用Python 3打印时出现语法错误
  8. python读取文件第n行-Python读取文件最后n行的方法
  9. python request-python3的request用法实例
  10. python实现文件下载-python实现文件下载的方法总结