Socket通讯

Socket通讯简单点理解就是通讯双方通过某个端口进行数据的相互传输,与常用的http的请求-响应方式不同,Socket通讯无需客户端向服务器发送请求,然后服务器在响应,直接就是进行数据传输。

一、Socket的类型

Socket有两种类型:
1、基于TCP协议传输数据的streamsocket;
2、基于UDP协议传输数据的datagramsocket。
传输过程如下:
这里写图片描述
通常我们都使用TCP协议传输
这里写图片描述
如上图Socket也分为服务器端和客户端,实际上一台机器既可以是服务端也可以是客户端,而两端 之间通过字节流传输数据

二、Socket的具体实现

这里的实现基于TCP协议的方式
1、首先在服务端先创建一个工作线程类来处理数据

public class MessageRunnable implements Runnable{
    private Socket socket=null;
    public MessageRunnable(Socket socket){
        this.socket=socket;
    }
    @Override
    public void run() {
        try {
            //获取输入输出流
            InputStream is=socket.getInputStream();
            OutputStream os=socket.getOutputStream();

            //把数据写回客户端
//          String toClientStr="稍等下..客服忙...";
//          os.write(toClientStr.getBytes("utf-8"));
//          os.flush();
            //停止socket输出(半关闭状态)
//          socket.shutdownOutput();

            //读取客户端数据
            BufferedReader bf=new BufferedReader(new InputStreamReader(is));
            String line=null;
            String dataFromClient="";
            while ((line=bf.readLine())!=null) {
                dataFromClient+=line;
            }
            System.out.println("来自客户端:"+dataFromClient);
            socket.shutdownInput();
            os.write(dataFromClient.getBytes("utf-8"));
            os.flush();

            os.close();
            is.close();
            socket.close();
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

主要是获取输入输出流的方法,输入流就是外界接收过来的数据流,输出流就是本地向外界发送的数据流

InputStream is=socket.getInputStream();
OutputStream os=socket.getOutputStream();

2、然后再主线程创建ServerSocket对象

ServerSocket service=new ServerSocket(SOCKET_PORT);

上面方法传递的参数是通讯的端口号
3、通过ServerSocket对象的accept的方法获取来自客户端的socket对象
如果有数据过来就往下执行,否则就处于堵塞状态

while(true){
                //监听客户送发过来的信息
                Socket socket=service.accept();
                new Thread(new MessageRunnable(socket)).start();
}

4、在客户端创建好Socket对象,因为是网络操作所以要授权和在子线程运行,所以这里通过handle的消息机制来更新UI

//构造用于发送socket线程
    private class SocketThread extends Thread{
        String message;
        SocketThread(String messsage){
            this.message=messsage;
        }
        @Override
        public void run() {
            try {
                socket=new Socket();
                socket.connect(new InetSocketAddress("192.168.1.100",8888),5000);

                //获取输入输出流
                InputStream is=socket.getInputStream();
                OutputStream os=socket.getOutputStream();
                BufferedReader bf=new BufferedReader(new InputStreamReader(is));
                os.write(message.getBytes("utf-8"));
                os.flush();

                String line=null;
                String buff="";
                while ((line=bf.readLine())!=null){
                    buff+=line+"\n";
                }
                //发消息用于展示界面
                Message msg=Message.obtain();
                msg.what=MESSAGE_FLAG;
                Bundle bundle=new Bundle();
                bundle.putString("text",buff);
                msg.setData(bundle);
                handler.sendMessage(msg);

                os.close();
                is.close();
                bf.close();
                socket.close();

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

//处理子线程消息
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what==MESSAGE_FLAG){
                Bundle bundle=msg.getData();
                String message=bundle.getString("text");
                tvDisplay.append("Server说:"+message+"\n");
            }
            super.handleMessage(msg);
        }
    };

客户端这边通过connect方法连接到服务端的端口实现双方的通讯

三、总结

Socket是对TCP(UDP)协议的应用,主要应用场景是实时通信、游戏之类的要求网络能快速回应而不像http协议那般要发送请求才会获取响应,socket发生的网络连接,端与端之间可以主动推送数据,使数据响应更为及时,当然这样长时间的实时响应是很耗电的,所以一般长时间没有数据传递都会关闭连接。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章