网络通信Socket的简单案例

发布于:2024-06-08 ⋅ 阅读:(142) ⋅ 点赞:(0)

1.客户端代码 

import java.io.*;
import java.net.Socket;

public class GreetingClient {
    public static void main(String[] args) throws IOException {
        //准备目的地参数
        String ip = "localhost";
        int port=6006;
        //建立工人
        Socket client = new Socket(ip, port);
        
        //建立外层管道
        InputStream is = client.getInputStream();
        OutputStream os= client.getOutputStream();
        
        //建立内层数据管道
        DataInputStream dis = new DataInputStream(is);
        DataOutputStream ois = new DataOutputStream(os);
        
        //输出和接收
        ois.writeUTF("xxx");
        System.out.println(dis.readUTF());
        //关闭
        client.close();
    }
}

2.服务端代码写法一

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class GreetingServer extends Thread{
    private ServerSocket serverSocket;
    public  GreetingServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        serverSocket.setSoTimeout(10000);
    }

    public void run(){
        while (true) {
            Socket server= null;
            try {
                server=serverSocket.accept();
                OutputStream os=server.getOutputStream();
                InputStream is=server.getInputStream();

                DataOutputStream dos = new DataOutputStream(os);
                DataInputStream dis = new DataInputStream(is);

                dos.writeUTF("xxx");
                dis.readUTF();

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

    public static void main(String[] args) throws IOException {
        //作为服务器端:只需准备监听端口信息
        int port = 6066;
        Thread t = new GreetingServer(port);//新建一个监听6066端口的线程对象,线程执行起来就是为了通信
        t.start();
    }
}

3.服务端写法二

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class GreetingServer2 extends Thread{
    private ServerSocket serverSocket;

    public void intialServerSocket(int port) throws IOException {
         serverSocket = new ServerSocket(port);
    }

    @Override
    public void run(){
        while (true) {
            Socket server= null;
            try {
                server=serverSocket.accept();
                OutputStream os=server.getOutputStream();
                InputStream is=server.getInputStream();

                DataOutputStream dos = new DataOutputStream(os);
                DataInputStream dis = new DataInputStream(is);

                dos.writeUTF("xxx");
                dis.readUTF();

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

    public static void main(String[] args) throws IOException {
        GreetingServer2 G2 = new GreetingServer2();
        G2.intialServerSocket(6060);
        G2.start();
    }
}

3.写法比较

1. 构造函数初始化

  • GreetingServer2 中,服务器套接字ServerSocket的初始化是在一个单独的方法intialServerSocket(int port)中进行的,并且这个方法没有遵循Java命名规范(应为initializeServerSocket)。这要求在创建类的实例后,还需要调用该方法来初始化服务器,这在使用上不够直观。

  • GreetingServer 则直接在其构造函数中完成了ServerSocket的初始化,这种方式更符合面向对象的设计原则,即对象在创建时就处于可用状态。此外,它还设置了一个超时时间setSoTimeout(10000),这是一个很好的实践,可以防止服务器无限期地等待连接。

2. 线程启动

  • 两者都通过继承Thread类并重写run方法来实现多线程服务,这是合理的。但在实际应用中,通常推荐使用Runnable接口而不是直接继承Thread,因为Java不支持多重继承,而实现接口可以提供更大的灵活性。不过,鉴于题目要求,这一点对比较两者不是决定性因素。

3. 异常处理与资源管理

  • 两个实现中对于Socket的创建、输入输出流的处理以及异常捕获基本一致,但都没有很好地处理资源关闭问题,如SocketInputStreamOutputStream等资源应该在使用完毕后及时关闭,以避免资源泄露。理想情况下,应该使用try-with-resources语句或者在finally块中确保资源被关闭。

4. 可读性和简洁性

  • GreetingServer 的代码结构更为简洁明了。通过构造函数初始化使得客户端代码(或主方法中的使用)更加直接,易于理解。同时,将端口号作为构造参数传递,使得该类更具通用性和可配置性。

网站公告

今日签到

点亮在社区的每一天
去签到