Android学习六:Socket 使用

1socket的作用

通过http去获取服务器的数据在有些情况下是行不通的,所有使用socket与服务器通信也是必须掌握的

2.代码

好了上代码,代码中有解释,首先是简单的服务端代码

package org.tonny;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class SockServer implements Runnable
{
    private static final int PORT = 55555;

    @Override
    public void run()
    {
        //用于响应客户端
        Socket client = null;
        
        //服务端socket
        ServerSocket server = null;
        try
        {
            //绑定端口,准备接受客户端的连接
            server = new ServerSocket(PORT);
            while (true)
            {
                System.out.println("Wait for connecting...");
                
                //这个操作是阻塞的,有客户端连接才会进行下一步操作
                client = server.accept();
                
                //读取客户端发送的数据
                BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                String msg = in.readLine();
                System.out.println("Client:  " + msg);
            }
        }
        catch (Exception e)
        {
            System.out.println("Server Receive: Error");
        }
        finally
        {
            try
            {
                //关闭套接字
                server.close();
                client.close();
            }
            catch (IOException e)
            {
                System.out.println("Server Receive: Error" + e.getMessage());
            }
        }
    }

    public static void main(String[] args)
    {
        Thread thread = new Thread(new SockServer());
        thread.start();
    }
}

接着是android客户端的代码

package org.tonny.client;

import java.io.BufferedWriter;
import java.io.IOException;
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.util.Log;
import android.view.View;
import android.widget.EditText;

public class ClientActivity extends Activity
{
    // 需要发送的信息写在这个控件中
    private EditText txtInfo = null;
    private static final int PORT = 55555;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_client);
        txtInfo = (EditText) this.findViewById(R.id.txtInfo);
    }

    public void onBtnSendClick(View view)
    {
        String msg = txtInfo.getText().toString();
        
        //不適用綫程通不过去,直接异常处理,这是因为android 3.0+以上 已经不建议在activity中添加耗时操作,要界面和数据脱离。4.0以上的通信都必须放到线程里去做 不能在UI线程。
        //解决办法,另起线程或Service处理socket。
        SockClient sock = new SockClient("192.168.1.106", PORT, msg);
        sock.start();
    }

    private final class SockClient extends Thread
    {
        private String ip;
        private int port;
        private String msg;

        public SockClient(String ip, int port, String msg)
        {
            this.ip = ip;
            this.port = port;
            this.msg = msg;
        }

        @Override
        public void run()
        {
            Socket client = null;
            try
            {
                Log.d("CLIENT", "Connecting...");
                // 与服务器获取连接
                client = new Socket(ip, port);
                // 获取 Client 端的输出流
                PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);
                out.println(msg);
            }
            catch (UnknownHostException e)
            {
                Log.e("CLIENT", "Error", e);
            }
            catch (IOException e)
            {
                Log.e("CLIENT", "Error", e);
            }
            catch (Exception e)
            {
                Log.e("CLIENT", "Error", e);
            }
            finally
            {
                try
                {
                    if (client != null && !client.isClosed())
                    {
                        client.close();
                    }

                }
                catch (IOException e)
                {
                    Log.e("TCP", "Error", e);
                }
            }
        }
    }
}

要注意的是,socket操作一定要在单独的线程中进行,否则会产生异常。

3.总结

还是一点,android操作socket的时候,应该在线程中执行,否则会报异常,为了这个花了不少时间调试,还是没搞定,最后问的度娘。

原文地址:https://www.cnblogs.com/supertonny/p/4452296.html