Android入门笔记 - 网络通信 - Socket

今天来学习一下android中通信方式中的socket。上两次我们分别使用了HttpURLConnection , 和 HttpClient来实现通信,他们都是在使用HTTP协议,Socket被称为套接字,使用的协议有TCP和UDP,TCP和UDP的区别在于TCP是可靠稳定的,自带容错处理等优点,所以效率要低一点。然后UDP就不那么稳定了,当使用UDP发送数据的时候,每次send,那么socket只管send,不会管send之后对方是否收到,是否顺序正确,所以UDP被称为不稳定的传输,但是其效率却很高,因为做的事情很简单。

今天我们学习socket是使用tcp协议,在android中使用socket其实就是使用java中的socket,看应用的包 java.net.*; 就知道。

我们来完成一个小的局域网聊天的程序,包含一个服务器,android应用作为客户端,一台手机发送信息后,服务器会转发给其他手机,很简单。代码比较多,后面附上下载地址,我们先来看怎么使用socket。

客户端:

客户端Socket使用步骤:

(1)Socket mSocket = new Socket( SERVER_IP, SERVER_PORT); // 两个参数分别为服务器ip地址,和服务器监听的端口号

(2)BufferedReader  mBufferReader = new BufferedReader(new InputStreamReader( mSocket.getInputStream()));  // 通过socket.getInputStream() 可以得到输入流,可从socket获取服务器发送的数据。为了能一行一行读取,我们将其转化为 BufferReader,可以使用BufferReader.readLine() 一行一行得去取等待在socket上的数据。

(3)PrintWriter  mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true); // 通过socket.getOutputStream() 可以得到输入流,就可以通过socket向服务器发送数据, 这里需要套上 PrintWriter 标准的接口,就可以使用 mPrintWriter.println(“ ..." ),直接发送数据。

(4)使用完后断开连接。

我们来看一看实例:

mSocket = new Socket(SERVER_IP, SERVER_POART);
mBufferReader = new BufferedReader(new InputStreamReader(
	mSocket.getInputStream()));
mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true);

如果没有报 Exception那就表示链接服务器已经成功,这时就可以使用 mBufferReader和 mPrintWrinter 来实现数据的收发。

读取数据:

                while (true) {
                    if (null != (mStrMsg = mBufferReader.readLine())) {
                        mStrMsg += "\n";
                        if(mStrMsg.trim().equals("exit")){
                            mHandler.sendMessage(mHandler.obtainMessage(2));
                            return ;
                        }
                        mHandler.sendMessage(mHandler.obtainMessage(0));
                    }
                }

发送数据:

    private View.OnClickListener sendListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String str = mEtMessage.getText().toString().trim();
            if(mPrintWriter == null){
                showToast("请先连接服务器!");
                return ;
            }
            mPrintWriter.println(str);
            mPrintWriter.flush();
            mEtMessage.setText("");
        }
    };

断开连接:

showToast("断开连接");
    try {
	mBufferReader.close();
	mPrintWriter.close();
	mSocket.close();
	mSocket = null;
	if (mGetMessageThread != null) {
	    mGetMessageThread = null;
	}
     } catch (IOException e) {
          e.printStackTrace();
     }

服务端:

在服务端我们需要有一个ServerSocket,这是用来接收连接请求的,当每接收到一个一个请求后就会返回一个Socket套接字,就可以使用这个套接字与客户端通信。注意:服务器端应该是一直运行,且可以接收很多连接的程序,服务器程序一定不能被关闭或者崩掉,所以在设计服务器的时候要考虑很多很多事情,我们这里只是简单的处理收到客户端请求连接,然后将其加入到list当中,如果收到消息,就将收到的消息转发给列表中其他所有socket,很简单的处理。

使用步骤:

(1)ServerSocket mServerSocket = new ServerSocket(SERVERPORT); // 创建监听连接ServerSocket

(2)不停监听 mServerSocket, 使用accept() 接收连接,如果侦测到连接,就启动一个线程,将返回值socket传入,那么每个线程就对应一个客户端,可以与客户端通信了。

(3)接下来就是 每个线程如果收到数据,就需要将消息转发给 客户单列表中所有其他用户。

(4)客户端断开链接后,清除客户socket信息。

启动监听连接,并启动一个线程池,当监听到连接请求时创建启动线程,并放入到线程池中运行:

        try {
            mServerSocket = new ServerSocket(SERVERPORT);
            mExecutorService = Executors.newCachedThreadPool();
            System.out.println("Server Start...");
            Socket client = null;
            while (true) {
                client = mServerSocket.accept();
                mClientList.add(client);
                mExecutorService.execute(new ThreadServer(client));
            }

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

线程中接收消息,以及转发消息:

    private class ThreadServer implements Runnable {
        private Socket mClient;
        private BufferedReader mBufferedReader;
        private PrintWriter mPrintWriter;
        private String mStrMsg;

        public ThreadServer(Socket client) throws IOException {
            this.mClient = client;
            mBufferedReader = new BufferedReader(new InputStreamReader(
                    mClient.getInputStream()));
            mStrMsg = "usr:" + this.mClient.getInetAddress() + " connected"
                    + ",total:" + mClientList.size();
            sendMessage(mStrMsg);
        }

        private void sendMessage(String msg) throws IOException {
            System.out.println(msg);
            for (Socket client : mClientList) {
                mPrintWriter = new PrintWriter(client.getOutputStream(), true);
                mPrintWriter.println(msg);
            }
        }

        @Override
        public void run() {
            try {
                while (null != (mStrMsg = mBufferedReader.readLine())) {
                    if (mStrMsg.trim().equals("exit")) {
                        mStrMsg = "user:" + mClient.getInetAddress() + " exit!"
                                + "total:" + (mClientList.size() - 1);
                        sendMessage(mStrMsg);

                        mPrintWriter = new PrintWriter(
                                mClient.getOutputStream(), true);
                        mPrintWriter.println("exit");

                        mBufferedReader.close();
                        mPrintWriter.close();
                        mClientList.remove(mClient);
                        mClient.close();
                        break;
                    } else {
                        mStrMsg = mClient.getInetAddress() + ":" + mStrMsg;
                        sendMessage(mStrMsg);
                    }
                }
            } catch (SocketException e) {
                // e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

如果没有网络基础,这个理解起来还是有点复杂的,下面贴了项目代码,大家自己去体会一下吧,使用socket其实很简单,主要是逻辑处理。

这里有几点需要注意的:

(1)android2.3之后不能再UI主线程中调用网络请求,会直接崩溃,所以需要使用handler来发送消息处理

(2)实例代码放在你的机子上不一定能使用,SERVER_IP为计算机在局域网的本机地址,需要自己修改。 android客户端需要连上计算机,这样客户端就能找到服务器了。

代码下载地址:

http://download.csdn.net/detail/u013647382/8273861

时间: 2024-10-17 13:25:48

Android入门笔记 - 网络通信 - Socket的相关文章

Android入门笔记 - 网络通信 - HttpClient

今天我们来学习怎么使用 Apache 为android提供的网络通信接口,如果要使用http协议,就需要使用 HttpClient. 使用HttpClient要比使用 HttpURLConnection更简单一些,我们来看看代码: 1. 使用get方法获取网络图片: 调用: mBtnGet.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Bitmap picture =

Android入门笔记 - 网络通信 - HttpURLConnection

Android中要与远程服务器通信有很多方法,今天我们来介绍使用http协议从远程服务器上获取数据. 在android中可以使用 一下三种接口和服务器进行http通信: 1. java标准接口:java.net.*; 2. apathe接口: org. apache. http. *; 3. android接口: android.net.*; 今天我们介绍 java的标准接口,接下来我们将介绍: 1. 使用get方法获取网络html文件 2. 使用post方法获取网络html文件 3. 使用ge

Android入门笔记1

按钮事件 ? 演示编辑框.文本显示.按钮事件 布局: ? 布局文件: <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="m

Android入门笔记2——获取传感器列表

? UI界面: ? 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" an

Android入门笔记(一)

第一部分,Android开发环境的搭建 1.去http://www.oracle.com/technetwork/java/javase/downloads/index.html下载最新版本jdk并安装,配置环境变量. 2.去http://www.eclipse.org/downloads/下载最新版本eclipse,并安装. 3.下载android sdk并安装,下载地址 http://pan.baidu.com/s/1i3ggwhn 4.下载ADT并安装,下载地址http://pan.bai

Android入门笔记 - 界面开发 - Animation

今天我们来看看Android中的动画效果,实例比较简单: AlphaAnimation:透明度动画 ScaleAnimation:缩放动画 TranslateAnimation:移动位置动画 RotateAnimation:旋转角度动画 先贴代码: 这个实例完全使用代码实现的,当然也可以使用xml文件实现,我们先来看这个实例: package com.example.demo5_03_animation; import android.os.Bundle; import android.anno

Android入门笔记 - 界面开发 - TextView,Button,EditText,Toast

今天简单介绍一下android中的控件资源,我们从一个登陆界面开始讲起,先贴代码: 准备工作:先在eclipse中创建一个android项目,我的项目名称是demo_login. (1)在项目文件夹的 res/layout/ 文件目录下打开 activity_main.xml : <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="f

Android入门笔记 - 数据存储 - SharedPreferences

接下来四篇我们来介绍Android中用于数据存储的四种方式: SharedPreferences Sqlite Files 网络 今天我们先来看一个最简单的:SharedPreferences. 这种数据存储方式是最简单,最轻便,也最实用的,但是只能用来储存基本数据类型.我们来看看怎么使用: 1. res/ layout/ activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/an

Android入门笔记 - 界面开发 - 帧动画

今天来介绍一下Android中的帧动画,帧动画其实就是一张一张的图片,以一定的顺序播放,然后形成动画. 先来上一张效果图: 图中两个按钮,start开始播放动画, stop结束动画,来看看代码: 1. res/ drawable / frame_animation.xml : <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schem