1.说明

Socket(套接字)是计算机网络编程用于实现网络通信的一种编程接口抽象概念
它提供了一种标准接口,使应用程序能够通过网络与其他计算机进行通信
Socket可以看作是应用程序与网络之间一个通信端点,类似于电话中的插座
通过Socket应用程序可以创建连接发送接收数据,以实现网络通信
Socket通常使用TCP/IP协议栈作为底层网络协议
但也可以与其他协议一起使用
如UDP(User Datagram Protocol)和ICMP(Internet Control Message Protocol)等。

Java基于TCP协议实现网络通信的类

服务端客户端使用Socket通信步骤

  1. 创建ServerSocket和Socket
  2. 打开连接到Socket的输入/输出
  3. 按照协议对Socket进行读/写操作
  4. 关闭输入输出流、关闭Socket

2.服务端编程

服务端使用ServerSocket编程步骤

  1. 创建ServerSocket对象绑定监听端口
  2. 通过accept()方法监听客户请求
  3. 连接建立后,通过输入读取客户发送请求信息
  4. 通过输出流向客户发送乡音信息
  5. 关闭相关资源
package edu.java.net.socket.tcp;

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;

/**
 * TCP Socket 套接字服务端
 */
public class ServerSocketDemo {
    public static void main(String[] args) throws Exception {
        // simpleServer();
        concurrentServer();
    }

    /**
     * 单线程服务端,只能接收一个客户端的请求,并且会话结束服务端自动停止
     */
    public static void simpleServer() throws IOException {
        // 基于TCP协议的Socket通信,实现用户登录服务

        // 1.创建一个服务器端Socket,即ServerSocket,指定绑定端口,并监听此端口
        // 1024-65535的某个端口
        ServerSocket serverSocket = new ServerSocket(10086);
        System.out.println("服务端已经启动,等待客户端的连接...");
        // 2.调用accept()方法开始监听,等待客户端的连接
        // 进程阻塞直到接收到客户请求
        Socket socket = serverSocket.accept();

        // 3.获取输出流,响应客户端的请求
        OutputStream os = socket.getOutputStream();
        PrintWriter pw = new PrintWriter(os);
        pw.write("欢迎您访问服务端!" + System.lineSeparator());
        pw.flush();

        // 4.获取输入流,并读取客户信息
        InputStream is = socket.getInputStream();

        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String info = null;
        while ((info = br.readLine()) != null) {
            System.out.println("服务端接收到消息:" + info);
            pw.write("服务端收到:" + info + System.lineSeparator());
        }
        pw.flush();
        // 关闭输入
        socket.shutdownInput();

        // 5.关闭资源
        pw.close();
        os.close();
        br.close();
        isr.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

3.客户端编程

客户端使用Socket编程步骤

  1. 创建Socket对象,指明需要连接的服务器地址端口号
  2. 连接建立后,通过输出流想服务器端发送请求信息
  3. 通过输入流获取服务响应信息
  4. 关闭响应资源
package edu.java.net.socket.tcp;

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

/**
 * TCP Socket 套接字客户端
 *
 */
public class ClientSocketDemo {
    public static void main(String[] args) throws Exception {

        // 1.创建客户端Socket,指定服务地址端口
        Socket socket = new Socket("localhost", 10086);

        // 2.获取输出流,向服务器端发送信息
        OutputStream os = socket.getOutputStream();
        // 字节输出流
        PrintWriter pw = new PrintWriter(os);
        // 将输出流包装打印
        // 注意结尾的换行提示服务端一行结束
        pw.write("用户名admin" + System.lineSeparator());
        pw.write("密码:123456" + System.lineSeparator());
        pw.flush();
        socket.shutdownOutput();

        // 3.获取输入流,并读取服务器端响应信息
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String info = null;
        while ((info = br.readLine()) != null) {
            System.out.println("客户端收到消息:" + info);
        }
        // 4.关闭资源
        br.close();
        is.close();
        pw.close();
        os.close();
        socket.close();

    }
}

4.服务端多线程编程

实际场景中,一个服务端往往可以支持多个客户端的连接,为多个客户端提供服务。

实现服务器与多客户端之间通信步骤

  1. 服务器端创建ServerSocket,循环调用accept()等待客户端连接
  2. 客户端创建一个socket并请求和服务器端连接
  3. 服务器端接受客户端请求,创建socket与该客户建立专线连接
  4. 建立连接的两个socket在一个单独的线程通信
  5. 服务器端继续等待新的连接
package edu.java.net.socket.tcp;

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;

/**
 * TCP Socket 套接字服务端
 */
public class ServerSocketDemo {
    public static void main(String[] args) throws Exception {
        concurrentServer();
    }

    /**
     * 多线程服务端,能同时接收多个客户端的请求,并且会话结束后关掉对应Socket通道,服务端继续运行
     */
    public static void concurrentServer() {

        int count = 0;
        try {
            @SuppressWarnings("resource")
            ServerSocket serverSocket = new ServerSocket(10086);
            while (true) {
                System.out.println("服务端已经启动,等待客户端的连接...");
                Socket socket = serverSocket.accept();
                count++;
                System.out.println("监听到客户端的连接数量=" + count);
                // 启动一个线程
                ServerThread serverThread = new ServerThread(socket);
                serverThread.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

// 服务器多线程处理的实际线程
class ServerThread extends Thread {

    private int serverName = this.hashCode();

    // 和本线程相关socket
    private Socket socket = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {

        try {
            // 1.获取输出流,响应客户端的请求
            OutputStream os = socket.getOutputStream();
            PrintWriter pw = new PrintWriter(os);
            pw.write(serverName + ">欢迎您访问服务端!" + System.lineSeparator());
            pw.flush();

            // 2.获取输入流,并读取客户端信息
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String info = null;
            while ((info = br.readLine()) != null) {
                System.out.println(serverName + ">服务端接收到消息:" + info);
                pw.write("服务端收到:" + info + System.lineSeparator());
            }

            pw.flush();
            socket.shutdownInput();

            // 3.关闭资源
            pw.close();
            os.close();
            br.close();
            is.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

原文地址:https://blog.csdn.net/bugzeroman/article/details/134788552

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_44726.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注