Android网络编程之Socket通信

      Socket(套接字)是一种通信机制,可以实现单机或跨网络进行通信,其创建需要明确的区分C(客户端)/S(服务器端),支持多个客户端连接到同一个服务器。有两种传输模式:

1)、面向连接的传输:基于TCP协议,可靠性高,但效率低;

2)、面向无连接的传输:基于UDP协议,可靠性低,但效率高;

        Android中,直接采用Socket通信应该是我们遇到的最低级的网络运用。尽管已经作了很大程度的抽象,但是纯粹的Socket通信,仍然给开发者留下很多细节需要处理,尤其在服务器端,开发者需要处理多线程以及数据缓冲等的设计问题。相对而言,处于更高抽象层的HTTP等,已经对Socket通信中需要处理的技术细节进行了很好的封装,开发者无须关心,因此,HTTP在网络开发中通常具有决定性的优势。

        Android在其核心库的java包中,提供了用于客户端的Socket class和用于服务器端的ServerSocket class,分别位于$SOURCE/libcore/luni/src/main/java/java/net/Socket.java和$SOURCE/libcore/luni/src/main/java/java/net/ServerSocket.java文件中。分析两个class的源码,可以看出封装考虑的很全面,只构造方法一向每个class都考虑了很多种使用情况。由于本人只是初学者,很多理解的不深入,这里只抛砖引玉的对两个class的构造方法分别介绍一种,就是我下面的程序中用到的:

Socket(String dstName, int dstPort):创建一个以流的方式(基于TCP协议)连接到目标机(这里可以理解为服务器)的客户端Socket;dstName是目标机的IP地址,dstPort是要连接的目标机的端  口号。这里要注意对端口的理解,它不能理解为物理上的一个接口,而是对计算机中一块特殊内存区域的形象表述。

ServerSocket(int aport):创建一个绑定到本机指定端口的服务端Socket;aport就是指定的本机端口。与上述客户端Socket对应,通过TCP连接时,ServerSocket创建后需要在aport端口上进行监听,等待客户端的连接。


启动 service 和 activity


        mContext.startService(new Intent(mContext, SocketService.class));

        Intent intent = new Intent();
        intent.setClass(mContext, SocketClientDemo.class);
        mContext.startActivity(intent);


service :服务端

package com.android.settings;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class SocketService extends Service {
    Thread mServiceThread;

    Socket client;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();

        mServiceThread = new Thread(new SocketServerThread());
    }

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);

        mServiceThread.start();
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
    }

    public class SocketServerThread extends Thread {
        private static final int PORT = 54321;

        private SocketServerThread() {
        }

        @Override
        public void run() {
            try {
                ServerSocket server = new ServerSocket(PORT);

                while (true) {
                    System.out.println("tian begin client connected");
                    client = server.accept();
                    System.out.println(" tian client connected");

                    BufferedReader reader = new BufferedReader(
                            new InputStreamReader(client.getInputStream()));
                    System.out.println(" tian read from client:");

                    String textLine = reader.readLine();
                    if (textLine.equalsIgnoreCase("EXIT")) {
                        System.out
                                .println(" tian EXIT invoked, closing client");
                        break;
                    }

                    System.out.println(textLine);

                    PrintWriter writer = new PrintWriter(new BufferedWriter(
                            new OutputStreamWriter(client.getOutputStream())));

                    System.out.println(" return tian read from client:"
                            + textLine);
                    writer.println(" tian ECHO from server: " + textLine);
                    writer.flush();

                    writer.close();
                    reader.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                System.err.println(e);
            }
        }

    }
}


package com.android.settings;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class SocketClientDemo extends Activity {
    private static final String SERVERIP = "127.0.0.1";
    private static final int SERVERPORT = 54321;

    private static final String TAG = "SocketClientDemo";

    TextView mMsgRev;
    EditText mMsgEdit;
    Button mMsgSendBtn;

    String mSendMsg;
    String mReceivedMsg;

    class MyThread implements Runnable {
        private String name;

        public MyThread(String name) {
            this.name = name;
        }

        public void run() {
            // for (int i = 0; i < 100; i++) {
            // System.out.println("线程开始:" + this.name + ",i=" + i);

            Log.d(TAG, "MyThread  execu");
            // }
        }
    };

    class MyThread2 extends Thread {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            Log.d(TAG, "MyThread2  execu");
        }
    };

    class MyThread3 extends Thread {

        private String name;

        public MyThread3(String name) {
            // super();
            this.name = name;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            Log.d(TAG, "MyThread3  execu" + "name=" + name);

            Socket socket = null;
            mSendMsg = mMsgEdit.getText().toString();

            try {
                socket = new Socket(SERVERIP, SERVERPORT);

                PrintWriter writer = new PrintWriter(new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())));
                writer.println(mSendMsg);
                writer.flush();

                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(socket.getInputStream()));
                mReceivedMsg = reader.readLine();

                Message meaage = mHander.obtainMessage();
                meaage.arg1 = 1;
                mHander.sendMessage(meaage);

                writer.close();
                reader.close();
                socket.close();
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.xml.beidou_detail_preference_settings);

        mMsgRev = (TextView) findViewById(R.id.receive_msg);
        mMsgEdit = (EditText) findViewById(R.id.edit_msg);
        mMsgSendBtn = (Button) findViewById(R.id.send_msg);

        mMsgSendBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                /*
                 * MyThread thread = new MyThread("00"); new
                 * Thread(thread).start();
                 *
                 * new MyThread2().start();
                 */

                MyThread3 thread3 = new MyThread3("33");
                thread3.start();

            }
        });
    }

    final Handler mHander = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub

            if (mReceivedMsg != null) {
                mMsgRev.setText(mReceivedMsg);
            } else {
                mMsgRev.setText("tian receive data error");
            }
            super.handleMessage(msg);
        }

    };
}


activity : 客户端


package com.android.settings;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
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.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class SocketClientDemo extends Activity {
    private static final String SERVERIP = "127.0.0.1";
    private static final int SERVERPORT = 54321;

    private static final String TAG = "SocketClientDemo";

    TextView mMsgRev;
    EditText mMsgEdit;
    Button mMsgSendBtn;

    String mSendMsg;
    String mReceivedMsg;

    class MyThread implements Runnable {
        private String name;

        public MyThread(String name) {
            this.name = name;
        }

        public void run() {
            // for (int i = 0; i < 100; i++) {
            // System.out.println("线程开始:" + this.name + ",i=" + i);

            Log.d(TAG, "MyThread  execu");
            // }
        }
    };

    class MyThread2 extends Thread {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            Log.d(TAG, "MyThread2  execu");
        }
    };

    class MyThread3 extends Thread {

        private String name;

        public MyThread3(String name) {
            // super();
            this.name = name;
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            Log.d(TAG, "MyThread3  execu" + "name=" + name);

            Socket socket = null;
            mSendMsg = mMsgEdit.getText().toString();

            try {
                socket = new Socket(SERVERIP, SERVERPORT);

                PrintWriter writer = new PrintWriter(new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())));
                writer.println(mSendMsg);
                writer.flush();

                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(socket.getInputStream()));
                mReceivedMsg = reader.readLine();

                Message meaage = mHander.obtainMessage();
                meaage.arg1 = 1;
                mHander.sendMessage(meaage);

                writer.close();
                reader.close();
                socket.close();
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.xml.beidou_detail_preference_settings);

        mMsgRev = (TextView) findViewById(R.id.receive_msg);
        mMsgEdit = (EditText) findViewById(R.id.edit_msg);
        mMsgSendBtn = (Button) findViewById(R.id.send_msg);

        mMsgSendBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                /*
                 * MyThread thread = new MyThread("00"); new
                 * Thread(thread).start();
                 *
                 * new MyThread2().start();
                 */

                MyThread3 thread3 = new MyThread3("33");
                thread3.start();

            }
        });
    }

    final Handler mHander = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub

            if (mReceivedMsg != null) {
                mMsgRev.setText(mReceivedMsg);
            } else {
                mMsgRev.setText("tian receive data error");
            }
            super.handleMessage(msg);
        }

    };
}



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。