江西金太阳教育官网(Java Socket编程例子)

江西金太阳教育官网:最近Java潘老师在协同底层项目开发web端需要使用到socket与其通信,实现消息传输,于是重拾那遗忘久矣的Java Socket网络编程技术。还记得当时学习Java Socket编程例子的时候是写了一个在线聊天室,有单聊有群聊,玩的的不亦乐乎,真正能体会到学Java技术原来这么有意思,不过今天潘老师就总结下最基础入门的Java Socket编程案例,并写把它融入到Java Web项目中,注意不是websocket哦~

1、Java项目Socket编程案例

我们目前的需求很简单,就是新建一个Java项目,然后有客户端,有服务端,客户端可以给服务端发消息,服务端收到消息然后返回一个响应给客户端。本案例基于TCP协议,如果想使用UDP的可以自行百度去哦。

第1步:创建服务端

由于服务端中有个accept方法是阻塞方法,用来监听端口等待客户端发送消息,所以我们服务端要单独开一个线程去监听端口,否则运行时会阻塞主线程,导致程序堵死,下面就是潘老师写的一个简单的服务端代码:

package com.panziye.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server extends Thread {
    // 服务端对象
    private ServerSocket serverSocket;
    // 默认监听8877端口
    private int port = 8877;

    // 构造方法,初始化服务端
    public Server() {
        try {
            // 创建Socket服务器对象,监听8877端口
            serverSocket = new ServerSocket(port);
            System.out.println("ServerSocket创建了....");
        } catch (Exception e) {
            System.out.println("ServerSocket创建出错....");
        }

    }

    // 重写run方法
    public void run() {
        System.out.println("服务端启动了,等待客户端发送消息....");
        // 循环监听,直到线程中断为止
        while(!this.isInterrupted()){
            try {
                // accept是阻塞方法,等待客户端发消息
                Socket socket = serverSocket.accept();
                if(socket != null && !socket.isClosed()){
                    // 处理socket消息
                    handleSocket(socket);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    }

    // 处理服务端接收到的socket消息
    private void handleSocket(Socket socket) {
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        OutputStream os = null;
        PrintWriter pw = null;
        StringBuffer result = new StringBuffer();
        try {
            is = socket.getInputStream();
            isr = new InputStreamReader(is);
            br = new BufferedReader(isr);

            String info = null;
            // 从流中读取客户端消息
            while ((info = br.readLine()) != null) {
                result.append(info);
            }
            // 输出消息
            System.out.println("我是服务器,客户端说:" + result);
            socket.shutdownInput();
            // 给客户端响应消息
            os = socket.getOutputStream();
            pw = new PrintWriter(os);
            pw.write("客户端你好,欢迎访问潘老师博客:https://www.panziye.com");

            pw.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            try {
                if (pw != null)
                    pw.close();
                if (os != null)
                    os.close();
                if (br != null)
                    br.close();
                if (isr != null)
                    isr.close();
                if (is != null)
                    is.close();
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭socket
     */
    public void closeSocketServer(){
        try {
            if(serverSocket != null && !serverSocket.isClosed()){
                serverSocket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
该服务端主要监听本机的8877端口,记得处理完客户端消息后一定要关闭IO流和socket,为了提高效率,也可以将handleSocket方法也单独开一个线程去处理,然后将其拆分成获取客户端消息方法、处理客户端消息方法、响应客户端消息方法以及关闭socket方法等。

第2步:创建客户端

客户端比较简单,主要就是和服务端建立连接,然后可以像服务端发送消息,并获取服务端返回的消息。例子代码如下:

package com.panziye.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class Client {
    // 主机地址
    private String host = "localhost";
    // 端口
    private int port = 8877;

    /**
     * 客户端向服务端发送消息
     */
    public String sendMessage(String msg) {
        // 响应结果
        StringBuffer result = new StringBuffer();
        BufferedReader br = null;
        InputStream is = null;
        OutputStream os = null;
        PrintWriter pw = null;
        Socket socket = null;
        try {
            // 和服务器创建连接
            socket = new Socket(host,port);
            System.out.println("和服务器已建立连接....");
            // 要发送给服务器的信息
            os = socket.getOutputStream();
            pw = new PrintWriter(os);
            // 给服务端发msg
            pw.write(msg);
            pw.flush();
            
            socket.shutdownOutput();
            
            // 从服务器接收的信息
            is = socket.getInputStream();
            br = new BufferedReader(new InputStreamReader(is));
            String info = null;
            while((info = br.readLine())!=null){
                result.append(info);
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            // 关闭流和socket
            try {
                if(br != null)
                    br.close();
                if(is != null)
                    is.close();
                if(os != null)
                    os.close();
                if(pw != null)
                    pw.close();
                if(socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result.toString();
    }
}

第3步:创建测试类

最后我们创建一个测试类,来测试效果,具体代码如下:

package com.panziye.socket;

public class SocketTest {
    public static void main(String[] args) {
        // 创建服务端线程并启动
        new Server().start();
        // 休眠3s等待服务端线程启动成功
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 创建客户端并发消息
        String response = new Client().sendMessage("你好潘老师...");
        System.out.println("服务端响应:"+response);
    }

}

最后我们运行,发现可以成功建立连接,发送消息,获得响应。查看控制台打印结果具体如图:
Java Socket编程例子并应用到Java Web项目

2、Socket编程案例应用到Java web项目

其实上面的代码如果你都理解了,那我们可以很轻松地将该案例应用到java web项目中,而难点就在于如何使服务端ServerThread随着web项目启动而启动。这里以Spring项目为例。

第1步:创建监听器

这里我们可以在Spring项目中新建一个监听器,实现ServletContextListener主要重写容器销毁和容器初始化方法:

package com.panziye.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.panziye.socket.ServerThread;

public class SocketServerListener implements ServletContextListener {
    
    private ServerThread serverThread;  
    
    /**
     * 销毁方法
     */
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        if (serverThread != null && serverThread.isInterrupted()) {  
            serverThread.interrupt();  
        }  
    }

    /**
     * 初始化方法
     */
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        if(serverThread == null) {
            // 创建线程
            ServerThread serverThread= new ServerThread (null);
            // 设为守护线程
            serverThread.setDaemon(true);
            // 启动socket线程
            serverThread.start();
        }
        
    }
}

第2步:配置web.xml

我们需要将创建好的监听器配置在web.xml中,具体如下:

<listener>
    <listener-class>com.panziye.listener.SocketServerListener</listener-class>
</listener>

最后启动项目就会发现,Socket服务端线程随着项目启动而启动了。

好了,以上就是Java Socket编程例子并应用到了Java Web项目中,其实里面的代码还有许多地方值得优化,你都学会了吗?

本文《江西金太阳教育官网(Java Socket编程例子)》由网赚联盟( wangzhuan.org.cn )整理或原创,感谢您的阅读。

随机文章

SEO小小课堂网
站长导航
搜素引擎算法
关键词排名优化
网站内容优化
站长导航
友情链接交换
搜素引擎算法

百度搜索“网赚联盟”即可找到本站,微信搜索“小小课堂网”关注小小课堂网公众号。网赚联盟( wangzhuan.org.cn )欢迎用户投稿,发布者:用户投稿,文章版权归作者所有,投稿文章不代表网赚联盟立场,中二少年发布为网赚联盟原创文章,转载请注明出处:https://wangzhuan.org.cn/22005.html