Socket通讯

来源:互联网 发布:java哈希表 编辑:程序博客网 时间:2024/05/17 06:45

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发生的网络连接,端与端之间可以主动推送数据,使数据响应更为及时,当然这样长时间的实时响应是很耗电的,所以一般长时间没有数据传递都会关闭连接。

0 0
原创粉丝点击