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

public class SocketCommunicationExample {
    public static void main(String[] args) {
        try {
            // 创建Socket对象,指定服务器IP地址和端口号
            Socket socket = new Socket("127.0.0.1", 8888);

            // 获取输入流,用于接收服务器发送的数据
            InputStream inputStream = socket.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            // 获取输出流,用于向服务器发送数据
            OutputStream outputStream = socket.getOutputStream();
            PrintWriter printWriter = new PrintWriter(outputStream);

            // 创建线程,用于接收服务器发送的数据并输出
            Thread receiveThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        String message;
                        while ((message = bufferedReader.readLine()) != null) {
                            System.out.println("接收到服务器发来的消息:" + message);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
            receiveThread.start();

            // 向服务器发送消息
            String sendMessage = "Hello, Server!";
            printWriter.println(sendMessage);
            printWriter.flush();

            // 关闭资源
            printWriter.close();
            outputStream.close();
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Socket通信是一种基于TCP/IP协议的网络通信方式。它通过在客户端和服务器之间建立连接,实现双向的数据传输。

在Java中,可以利用Socket类进行Socket通信的实现。客户端通过创建一个Socket对象,指定服务器的IP地址和端口号来连接服务器。然后,通过获取输入流和输出流来进行数据的接收和发送。

上述代码中,我们创建了一个Socket对象,并指定了服务器的IP地址和端口号。通过该Socket对象,我们可以获取输入流和输出流。在这个例子中,我们使用了一个线程来接收服务器发送的消息,并输出到控制台。同时,我们也向服务器发送了一条消息。

需要注意的是,在实际应用中,Socket通信一般是存在于一个独立的线程中,以免阻塞主线程的执行。同时,为了确保资源能够被正确关闭,我们使用了try-catch-finally结构来处理异常并关闭相关的资源。