网络套接字——Socket网络编程(TCP编程详解)

目录

上一篇章当中已经介绍了UDP的使用,接下来详细介绍TCP的套接字,网络编程模块

ServerSocket介绍

ServerSocket是创建TCP服务端的Socket的api

构造方法

方法签名 方法说明
ServerSocket(int port) 创建一个服务端流套接字Socket,并绑定到指定端口
Socket accept() 监听指定端口,有客户端连接之后,返回一个服务端Socket对象,并基于该Socket建立与客户端的连接,否则阻塞等待
void close() 关闭套接字

Socket介绍

Socket是客户端的Socket,或服务端中接收到的客户端建立连接(accept方法)的请求后,返回的服务端Socket

用于保存对端信息,及时用于与对方进行收发数据的

构造方法

方法签名 方法说明
Socket(String host,int port) 创建一个客户端流套接字Socket,并于对应IP的主机上,对应端口的进程建立连接
InetAddress getInetAddress() 返回套接字所连接的地址
InputStream getInputStream() 返回套接字输入流
OutputStream getOutputStream 返回此套接字的输出流

代码示例

在此处实现的这个是一个回显服务器,就会发现与UDP的差别是非常大的,字节流使用,多次处理信息,保存对端信息

服务器:

java 复制代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * 服务端
 */
public class TcpEchoServer {
    private ServerSocket serverSocket =  null;//这个主要是对服务器使用的

    // 1. 构造方法,绑定服务器这边的端口
    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }

    // 2. 程序启动
    public void start() throws IOException {
        System.out.println("服务器启动");
        while (true){//服务端需要持续不断的处理请求
            Socket clientSocket = serverSocket.accept();//先处理客户端发来的连接,如果没有发来链接,就会出现阻塞
            processConnection(clientSocket);//对客户端发来的数据进行处理
        }
    }

    public void processConnection(Socket clientSocket){
        //接下来可以读取请求,根据请求计算响应,返回响应三步走
        // Socket 对象内部包含了两个字节流对象,可以把这两字节流对象获取,完成后续读与写操作
        // 因为再TCP当中是字节流的方式进行读取的
        try (InputStream inputStream = clientSocket.getInputStream();
             OutputStream outputStream = clientSocket.getOutputStream()){
            // 一次连接,可能会涉及多次请求/响应
            while (true){
                // 1. 请求读取并进行解析
                Scanner scanner = new Scanner(inputStream);
                if(!scanner.hasNext()){
                    //读取完毕,客户端下线
                    System.out.println("客户端下线");
                    break;
                }

                // 使用next接收,就是有一个约定,客户端发来的请求,一定需要是文本数据
                String request = scanner.next();

                // 2. 根据请求计算相应
                String response = process(request);

                // 3. 把响应写给客户端, 把OutputStream使用PrinterWriter包裹
                PrintWriter writer = new PrintWriter(outputStream);
                //使用 PrintWriter的println方法,把响应返回给客户端
                //此处的println,不是print就是为了在结尾上加上/n结束标志
                writer.println(response);//此时相当于把内容放到了缓冲区上

                //需要加一个刷新缓冲区的操作
                writer.flush();
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            //在此处加上关闭操作
            try {
                clientSocket.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

    public String process(String request){
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer server = new TcpEchoServer(9090);
        server.start();;
    }

}

客户端:

java 复制代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

/**
 * 客户端
 *
 */
public class TcpEchoClient {
    private Socket socket;

    // 1. 构造方法
    // 要和服务器通信,需要知道服务器所在的位置
    public TcpEchoClient(String serverIp,int serverPort) throws IOException {
        socket = new Socket(serverIp,serverPort);
    }
    
    // 正式请求
    public void start() throws IOException {
        System.out.println("客户端启动");

        // 从控制台读取数据
        Scanner scannerConsole = new Scanner(System.in);
        
        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()){
            while (true){
                // 1. 从控制台输入字符串
                String request = scannerConsole.next();
                
                // 2. 把请求发送给服务器
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(request);//作用就是为了进行换行
                
                printWriter.flush();
                
                // 3. 从服务器读取响应
                Scanner scannerNetwork = new Scanner(inputStream);
                String response = scannerNetwork.next();
                
                //4. 把相应打印出来
                System.out.println(response);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            socket.close();
        }
    }

    public static void main(String[] args) throws IOException {
        TcpEchoClient client = new TcpEchoClient("127.0.0.1",9090);
        client.start();
    }
}

上述的两种写法可以说是相差是非常大的差别的,还是需要进行练习!

相关推荐
golang学习记3 分钟前
IntelliJ IDEA 2025.3 重磅发布:K2 模式全面接管 Kotlin —— 告别 K1,性能飙升 40%!
java·kotlin·intellij-idea
爬山算法6 分钟前
Hibernate(89)如何在压力测试中使用Hibernate?
java·压力测试·hibernate
闲人编程15 分钟前
使用FastAPI和WebSocket构建高性能实时聊天系统
websocket·网络协议·网络编程·fastapi·持久化·实时聊天·codecapsule
惊讶的猫19 分钟前
OpenFeign(声明式HTTP客户端)
网络·网络协议·http·微服务·openfeign
暮色妖娆丶28 分钟前
SpringBoot 启动流程源码分析 ~ 它其实不复杂
spring boot·后端·spring
消失的旧时光-194329 分钟前
第十四课:Redis 在后端到底扮演什么角色?——缓存模型全景图
java·redis·缓存
BD_Marathon30 分钟前
设计模式——依赖倒转原则
java·开发语言·设计模式
BD_Marathon34 分钟前
设计模式——里氏替换原则
java·设计模式·里氏替换原则
Coder_Boy_36 分钟前
Deeplearning4j+ Spring Boot 电商用户复购预测案例中相关概念
java·人工智能·spring boot·后端·spring
css趣多多38 分钟前
add组件增删改的表单处理
java·服务器·前端