美文网首页
Socket 用法

Socket 用法

作者: 蛋蛋不哭 | 来源:发表于2016-05-21 09:33 被阅读176次

    什么是Socket ?

    网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

    简介 :

    Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。

    架构 :

    socket.jpg 流程.jpg

    我们先来写服务端,其实服务端就是一个Socket通信,java文件

    • ChartService.java

    public class ChartService {
    
        //用来存储多个客户端发来的请求
        List<Socket> client = new ArrayList<Socket>();
        
        //开始 的启动方法
        public void startServer(){
            try {
                ServerSocket ss = new ServerSocket(12345);
                //我们写一个循环来让它一直处于监听的状态 
                while(true){
                    Socket socket = ss.accept();
                    client.add(socket);
                    this.new newThread(socket).start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        //我们写一个线程来执行来存储客户端发来的聊天数据
        class newThread extends Thread{
            Socket s ;
            BufferedReader bReader;
            public newThread(Socket s) {
                super();
                this.s = s;
                //用于接收数据 
                try {
                    bReader = new BufferedReader(new InputStreamReader(s.getInputStream(),"utf-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            @Override
            public void run() {
                super.run();
                String data=null;
                try {
                    while((data=bReader.readLine())!=null){
                        //遍历集合client
                        for(Socket s : client){
                            //輸出發送的數據
                            s.getOutputStream().write((data+"\n").getBytes());
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //main方法,用於啟動java程序
        public static void main(String[] args) {
            new ChartService().startServer();
        }
    }
    
    

    客户端,我们就要把数据传到服务端,再从服务端获取传过去的数据,显示在文本框中,,

    • main.xml

        <EditText
            android:id="@+id/tv"
            android:layout_width="fill_parent"
            android:layout_height="300dp"
            android:enabled="false"
             />
    
        <EditText
            android:id="@+id/et_name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:hint="昵称" />
    
        <EditText
            android:id="@+id/et_chart"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:hint="请输入聊天" />
    
        <Button
            android:id="@+id/send"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="发送" />
    
    • MainActivity.java

    public class MainActivity extends Activity implements OnClickListener {
    
        private EditText et_name, et_chart;
        private EditText show;
        private Button send;
        Socket socket;
        Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 0x12) {
                    String chat = show.getText().toString();
                    String chat1 = msg.getData().getString("chart");
                    show.setText(chat + "\n\n" + chat1);
                }
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            iviview();
    
            try {
                //设置本机的ip地址  端口号为服务端的端口号
                socket = new Socket("172.20.58.145", 12345);
                //利用线程来启动
                new ChartTherad(socket, handler).start();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        //初始化控件
        private void iviview() {
            et_name = (EditText) findViewById(R.id.et_name);
            et_chart = (EditText) findViewById(R.id.et_chart);
            show = (EditText) findViewById(R.id.tv);
            send = (Button) findViewById(R.id.send);
            send.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            if (v == send) {
                String name = et_name.getText().toString();
                String chart = et_chart.getText().toString();
                String data = name + ":" + chart + "\n";
                // 判断一下socket的值
                if (socket != null) {
                    // 我们就输出这个data
                    try {
                        // 传给服务器输出流(也就是发送数据)
                        socket.getOutputStream().write(data.getBytes("utf-8"));
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        class ChartTherad extends Thread {
            Socket client;
            Handler handler;
    
            public ChartTherad(Socket client, Handler handler) {
                super();
                this.client = client;
                this.handler = handler;
            }
    
            @Override
            public void run() {
                super.run();
                //用于接收从服务端获取的数据
                BufferedReader br;
                try {
                    // 接受传过来的输入流
                    br = new BufferedReader(new InputStreamReader(
                            client.getInputStream(), "utf-8"));
                    while (true) {
                        String content = br.readLine();
                        // 传给主线程 进行更新
                        Bundle bundle = new Bundle();
                        bundle.putString("chart", content);
                        Message msg = new Message();
                        msg.setData(bundle);
                        msg.what = 0x12;
                        handler.sendMessage(msg);
                    }
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • 权限:

    <uses-permission android:name="android.permission.INTERNET"/>
    

    注:4.0后会阻塞主线程的进程,因此都要开线程执行,这里主线程没有开线程,所以可用4.0以下版本的模拟器运行,,

    相关文章

      网友评论

          本文标题:Socket 用法

          本文链接:https://www.haomeiwen.com/subject/ycanrttx.html