当前位置: 首页 > 工具软件 > SAEA.Socket > 使用案例 >

Java SE之Socket

上官飞
2023-12-01

2021-05-14 周五下午Java课代码记录

1.整体代码

先上代码全文,整节课老师的代码全部包含在下方代码块中

注意: package 和 import 均不包含在代码块中,需要自行添加

tips:复制代码虽然方便,实践更重要

 代码全文后有我个人还原的上课过程,仅供思路参考

1.1. MyServerSocket类


 * @author yangshiwei
 * @Description 服务端
 *              1:接收客户端请求
 *              2:输出客户端发来的消息
 * @date 2021/5/14-14:41
 */
public class MyServerSocket {
    private int port;
    private ServerSocket serverSocket;

    public MyServerSocket(int port) {
        this.port = port;
        try {
            this.serverSocket = new ServerSocket(port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void getRequest() {
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;

        try {
//            获取输入流,接受客户端传递的消息
            inputStream = serverSocket.accept().getInputStream();
//            提高效率
            inputStreamReader = new InputStreamReader(inputStream);
//            加入缓冲区
            bufferedReader = new BufferedReader(inputStreamReader);

            String clientInfo = null;

            if ((clientInfo = bufferedReader.readLine()) != null) {
                System.out.println("client request info is: " + clientInfo);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
//            服务端的资源必须关闭
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                inputStreamReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void sendResponse() throws Exception {

    }

    public static void main(String[] args) throws Exception {
        System.out.println("客户端已启动");

        new MyServerSocket(8080).getRequest();

    }
}

1.2. MyClientSocket类


/**
 * @author yangshiwei
 * @Description 客户端:
 *              1:访问服务器端
 *              2:发送一句话
 * @date 2021/5/14-15:01
 */
public class MyClientSocket {
    public void sendMsg(String address, int port) throws IOException {
        Socket socket = null;
        OutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter =null;
        try {
//            1.绑定服务端端口
            socket = new Socket(address, port);

//            2.向端口发送信息
            outputStream = socket.getOutputStream();
            outputStreamWriter = new OutputStreamWriter(outputStream);

//            3.将请求信息写入输出流
            outputStreamWriter.write("this is client' request");

//            4.刷新缓存
            outputStream.flush();

            outputStreamWriter.close();
            outputStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (outputStreamWriter != null) {
                outputStreamWriter.close();
            }
            if (outputStream != null) {
                outputStream.close();

            }
            if (socket != null) {
                socket.close();
            }
        }
    }

    public static void main(String[] args) {
        try {
            new MyClientSocket().sendMsg("127.0.0.1", 8080);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2. 代码分析

 蓝色字体为本节课主要知识点,红色字体属于之前已经学习过的知识点,非红色字体看不懂,应认为是我语言表达能力有问题

2.1. 课程分析

建立MyServerSocket和MyClientSocket类,利用IO流,通过ServerSocket,解决网络通信问题。其中,使用异常处理,解决程序运行中遇到的问题

2.2. 过程分析

MyServerSocket类中,先新建两个对象:port 端口号 ;serverSocket 连接。

一开始老师上课的时候建了三个对象,包括address IP地址,后来发现服务端构建serverSocket不需要传入IP地址,最后删掉了。

构造函数只需要传入port。

public MyServerSocket(int port) {
        this.port = port;
        try {
            this.serverSocket = new ServerSocket(port);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

MyServerSocket类中,有两个功能函数,分别是getRequest();用来获取客户端的信号;sendRespone();用于返回客户端信息,本节课由于时间原因,只实现了第一个函数。

getRequest() 函数,一共分为五个步骤

1:获取字节输入流,用于接受客户端传递的消息。

2:生成字符输入流,用于保存字节输入流的信息,提高效率。

3:将获取到的字符流,存入生成的缓冲区

4:将缓冲区中的文字输出。

5:结束连接,关闭资源

其中第五步非常重要,服务器端没有关闭资源的话会导致程序无法运行,我就因为只关闭了客户的资源,没有关闭服务器端的资源,研究半天,蒸无语。

主函数中建立连接传入的参数,端口号:8080,可以为各种端口号,只要保证服务器端和客户端的端口号一样,并且不要使用已经规定好的端口,具体可以复习一下计算机网络的端口相关知识。

MyClientSocket类中,只有一个sendMsg()函数,传入的是访问的Ip地址和端口号。

一共也是分为五个步骤

1:绑定服务器端口。

2:向端口发送信息

3:将请求信息写入输出流

4:刷新缓存。

5:信息传输完成,关闭资源

主函数传入的ip地址可以是127.0.0.1,也可以写localhost。

2.3. 扩展

Server端的另一个函数是返回客户端一个确认消息,因此Client端也要生成一个接受信息的IO流,我写了好久,运行起来都不太对劲,没办法把自己的代码给大家参考。

大家也可以在局域网的环境下试试,一个电脑开启Server端,一个电脑开启Client端,Ip地址输入服务端的ip地址,端口号相同,理论上应该可以接收到信息,但我还没试过,大家有空可以试试看,要注意需要在同一个网络下测试。

以上就是本节课的全部内容以及我的一些个人看法,祝大家周末快乐,本节课内容很多,我自己也还不太理解,等我完全理解之后也许会再写一篇。

 类似资料: