发表于: 2017-07-01 23:49:57

1 1056


一今天完成的事情:

今天准备评审的,结果今天方案太多,没有轮的上,大佬们没时间.

 今天想说一下socket编程

我们在http中使用soket编程很多

 长连接,短链接:       

短链接:

    短链接的工作方式是这样的:建立连接--发送数据--关闭连接。规范一点的说法就是:每次进行数据传输时,需要首先建立TCP连接,传输完数据之后就关闭连接。下次有数据传输的时候再家里连接。比如说咱们常用的HTTP连接(当然HTTP连接也可以作为一种长连接)。

    

长连接:

    长连接的工作方式是这样的:建立连接--发送数据--保持连接--发送数据........--关闭连接

     规范一点就是:在一个TCP连接之内可以多次的进行数据传输。


两者的应用场景:

    长连接因为需要长时间的保持连接,所以对网络资源或这端口的占用十分的严重,所以长连接常用于频繁操作的任务,并且连接数不是非常大。

    短链接则相反,对于那些不是频繁操作的任务,可以选择短链接,而且短链接可以支持非常大的任务数,毕竟它对资源的占用有限。

    

            

        SOCKET连接的一个基本套路:服务器监听--客户端端请求--连接确认。


        


        


        一般来说,我们在进行SOCKET编程的时候,基本步骤:

        1、首先就是在服务端创建一个ServerSocket,对某个端口进行监听。

        

        2、在客户端创建SOKET,对某个地址进行请求


        3.服务端和客户端建立连接之后,通过IO流进行数据的传输。


        4、第四步:关闭连接,释放资源


        基本的步骤就是上面那样的,咱们来撸点代码来具体看一下。


服务器端:

public class SocketListenTest implements InitializingBean {

    /**

     *在这里,实现InitializingBean,在工程应用启动之后,就会启动afterPropertiesSet(),从而实现对端口的监听

     */

    private static final Logger logger = LoggerFactory.getLogger(SocketListenTest.class);

    //定义线程池,实现服务器的多线程的处理请求

    private static ExecutorService threadPool  = Executors.newFixedThreadPool(5);


    @Override

    public void afterPropertiesSet() throws Exception {

        logger.info("ServerSocket监听开始,开始时间:"+ DateUtil.getStringFromDate(new Date(),DateUtil.FORMAT_DATETIME));


        new Thread(new ServerSocketListen()).start();


        logger.info("ServerSocket监听结束,开始时间:"+ DateUtil.getStringFromDate(new Date(),DateUtil.FORMAT_DATETIME));


    }


    class ServerSocketListenimplements Runnable{


        @Override

        public void run() {

            try{

                /**

                 * 第一步:创建ServerSocket,监听9999,也就是咱们说的服务端进行监听

                 */

                ServerSocket serverSocket = new ServerSocket(9999);

                logger.info("创建服务器端Socket,绑定并监听端口,端口号:"+9999);

                Socket acceptSocket = null;

                while(true){

                    /**

                     * 第二步:通过ServerSocket创建服务器Socket,用于与客户端进行数据传输

                     */

                    acceptSocket = serverSocket.accept();

                    threadPool.submit(new SocketDealThread(acceptSocket));

                }

            }catch(Exception e){

                String msg = "监听线程异常结束,时间:"+DateUtil.getStringFromDate(new Date(),DateUtil.FORMAT_DATETIME);

                logger.error(msg,e);

            }


        }

    }


    class SocketDealThread implements Runnable{

        private Socket socket;

        private SocketDealThread(Socket socket){

            this.socket = socket;

        }

        @Override

        public void run() {

            DataInputStream dataInputStream = null;

            DataOutputStream dataOutputStream = null;

            try{

                logger.info("处理Socket请求,获取输入流,并读取客户端信息");

                /**

                 * 第三步:获取输入流,调用socket.getInputStream()获取输入流,获取客户端输入的数据

                 * 注意:这里用了readUTF(),采用了UTF-8编码对流数据进行转换,最好客户端写入数据的时候使用writeUTF()

                 */

                dataInputStream = new DataInputStream(socket.getInputStream());

                String contentStr = dataInputStream.readUTF();

                logger.info("处理Socket请求,请求报文:"+contentStr);


                /**

                 * 第四步:调用socket.getOutputStream()获取输出流,向客户端进行数据的输出

                 */

                dataOutputStream = new DataOutputStream(socket.getOutputStream());

                dataOutputStream.writeUTF("YES");


            }catch(Exception ex){

                String strErrorMsg = "处理Socket请求异常";

                logger.error(strErrorMsg, ex);

            }finally{

                /**

                 * 第五步:关闭socket的资源

                 */

                logger.info("处理Socket请求,资源关闭开始");

                try {

                    if(dataOutputStream != null){

                        dataOutputStream.close();

                    }

                } catch (IOException e) {

                    logger.error("关闭写管道异常",e);

                }

                try {

                    if(dataInputStream != null){

                        dataInputStream.close();

                    }

                } catch (IOException e) {

                    logger.error("关闭读管道异常",e);

                }

                try {

                    socket.close();

                } catch (IOException e) {

                    logger.error("关闭socket异常",e);

                }

                logger.info("处理Socket请求,资源关闭完成");

            }

        }

    }

}




客户端代码:

 public void clientSocketTest(){

        Socket socket = null;

        DataOutputStream dataOutputStream = null;

        DataInputStream dataInputStream = null;

        try{


            /**

             * 第一步:创建客户端Socket,此时需要指定请求服务器的IP地址和端口号

             *

             */

            socket = new Socket("localhost",9999);


            /**

             * 第二步:获取输出流,向服务端写出数据,调用socket.getOutputStream()

             */

            dataOutputStream = new DataOutputStream(socket.getOutputStream());

            String str = "这是一条来自客户端socket的请求数据";

            dataOutputStream.writeUTF(str);


            /**

             * 第三步:获取输入流,读取服务器返回的数据

             */

            dataInputStream = new DataInputStream(socket.getInputStream());


            String returnStr= dataInputStream.readUTF();

            logger.info("服务器返回的报文:"+returnStr);

        }catch(Exception e){

            String msg = "客户端Socket出现异常,时间:"+ DateUtil.getStringFromDate(new Date(), DateUtil.FORMAT_DATETIME);

            logger.error(msg,e);

        }finally{

            /**

             * 第四步:关于socket连接及其相关资源

             */

            logger.info("处理Socket请求,资源关闭开始");

            try {

                if(dataOutputStream != null){

                    dataOutputStream.close();

                }

            } catch (IOException e) {

                logger.error("关闭写管道异常",e);

            }

            try {

                if(dataInputStream != null){

                    dataInputStream.close();

                }

            } catch (IOException e) {

                logger.error("关闭读管道异常",e);

            }

            try {

                socket.close();

            } catch (IOException e) {

                logger.error("关闭socket异常",e);

            }

            logger.info("处理Socket请求,资源关闭完成");


        }

    }




        以上就是SOCKET连接的基本步骤,当然上面实现的是SOCKET短连接的实现方式。当然也可以使用SOCKT的长连接。

    

SOCKET实现长连接,有一个心跳机制。大体的思路是这样的:

    客户端:

    客户端每隔一定的时间往服务器端发送一段报文,假设我们每隔1一分钟往服务器端发送一段报文。


    服务器端:服务器端要有一个相应的检测机制,没隔一段时间(我们假设两分钟)去检测有没有收到客户端发来的该段报文。如果没有,则断开连接。

    

    

二、遇到的问题无

三、明天计划的事情:

四、收获:最近对源码很感兴趣,:等复盘任务做完了多去看看


返回列表 返回列表
评论

    分享到