Android中基于Socket的网络通信

1. Socket介绍

2. ServerSocket的建立与使用

3. 使用ServerSocket建立聊天服务器-1

4. 使用ServerSocket建立聊天服务器-2

5. 在Android中创建Socket客户端

------------------------------------------------------------------

工程源码:SocketDemo.zip

服务器端 - Java工程:ServerSocketDemo

客户端 - Android工程:AndroidSocketClient

------------------------------------------------------------------

1. Socket介绍

    Socket 又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。ServerSocket 用于服务器端,Socket 是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个 Socket 实例,操作这个实例,完成所需的会话。

    对于一个网络连接来说,套接字是平等的,没有差别, 不会应用在服务器端或者客户端而产生不同级别。

    不管是Socket还是ServerSocket 他们的工作都是通过Socket类及其子类完成。

   * 基于TCP连接,数据传输有保障

   * 适于建立长时间的连接

   * 通常用于即时通信

 

2. ServerSocket的建立与使用

3. 使用ServerSocket建立聊天服务器-1

    3.1 建立Java工程: ServerSocketDemo

        * ChatSocket.java

public class ChatSocket extends Thread {

    Socket socket;

    public ChatSocket(Socket s) {
        socket = s;
    }

    public void out(String out) {
        try {
            socket.getOutputStream().write(out.getBytes("UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        int count = 0;
        while (true) {
            count++;
            out("loop : " + count + ", \t");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

    * ServerListener.java

public class ServerListener extends Thread {

    @Override
    public void run() {
        ServerSocket serverSocket;
        try {
            serverSocket = new ServerSocket(12345);
            while (true) {
                // 监听 12345端口
                Socket socket = serverSocket.accept();
                // 建立连接
                JOptionPane.showMessageDialog(null,
                        "There is an client access 12345 port");
                new ChatSocket(socket).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

    * MyServerSocket.java

public class MyServerSocket {

    public static void main(String[] args) {
        new ServerListener().start();
    }

}

    3.2 管理员权限打开 CMD窗口: telnet localhost 12345

   

   

    两个线程互补影响

   

 

4. 使用ServerSocket建立聊天服务器-2

    3中的两个Client不能相互通信

    所以在3的基础上修改项目:

    * 新建 ChatManager.java(单例模式) 来管理Socket连接

    * 修改: ServerListener.java, 来存储 所有连接 到 Server的 Socket

    *  在ChatSocket线程中,增加接收消息的 代码

    具体项目可以看源代码

 

5. 在Android中创建Socket客户端

    在Android中创建Socket客户端。使用Socket建立客户端链接,并且在AsyncTask中执行网络读写的任务,将用户输入的内容发送到服务器,并接收服务器发来的数据,显示到界面上。开启多个虚拟机模拟多人聊天效果。

    拿4中的Java项目作为服务器端

    创建 Android客户端 项目: AndroidSocketClient

        建立一个如图所示的布局:

       

public class MainActivity extends Activity {

    EditText etIP, etComposing;
    TextView tvContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etIP = (EditText) findViewById(R.id.etIP);
        etComposing = (EditText) findViewById(R.id.etComposing);
        tvContent = (TextView) findViewById(R.id.tvContent);

        findViewById(R.id.btnConn).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                connect();
            }
        });
        findViewById(R.id.btnSend).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                send();
            }
        });

    }

    Socket socket = null;
    BufferedWriter bw;
    BufferedReader br;

    public void connect() {
        AsyncTask<Void, String, Void> read = new AsyncTask<Void, String, Void>() {

            @Override
            protected Void doInBackground(Void... params) {
                try {
                    socket = new Socket(etIP.getText().toString(), 12345);
                    bw = new BufferedWriter(new OutputStreamWriter(
                            socket.getOutputStream()));
                    br = new BufferedReader(new InputStreamReader(
                            socket.getInputStream()));
                    publishProgress("@success");
                    try {
                        String line;
                        while ((line = br.readLine()) != null) {
                            publishProgress(line);
                        }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } catch (UnknownHostException e) {
                    // TODO Auto-generated catch block
                    publishProgress("@fail");
                    e.printStackTrace();
                } catch (IOException e) {
                    publishProgress("@fail");
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onProgressUpdate(String... values) {
                if (values[0].equals("@success")) {
                    tvContent.append("Success connect to Server\n");
                } else if(values[0].equals("@fail")) {
                    tvContent.append("Connect to Server Fail\n");
                } else{
                    Log.d("CARLOZ", "Other: " + values[0]);
                    tvContent.append("Other: " + values[0] + "\n");
                }
                super.onProgressUpdate(values);
            }
        };
        read.execute();
    }

    public void send() {
        try {
            tvContent.append("Me: " + etComposing.getText().toString() + "\n");
            bw.write(etComposing.getText().toString() + "\n");
            bw.flush();
            etComposing.setText("");// clear
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

 

运行效果如下,下面的弹框是Java程序的Dialog

 

同时开两台虚拟机的运行效果如下:

 

posted @ 2015-08-27 14:35  carlo-z  阅读(681)  评论(0编辑  收藏  举报