网络套接字——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();
    }
}

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

相关推荐
Victor3567 小时前
Redis(172)如何使用Redis实现分布式队?
后端
路边草随风9 小时前
java实现发布spark yarn作业
java·spark·yarn
为爱停留9 小时前
Spring AI实现MCP(Model Context Protocol)详解与实践
java·人工智能·spring
盐焗西兰花11 小时前
鸿蒙学习实战之路 - 网络重连最佳实践
网络·学习·harmonyos
汝生淮南吾在北12 小时前
SpringBoot+Vue饭店点餐管理系统
java·vue.js·spring boot·毕业设计·毕设
无限大615 小时前
计算机十万个为什么--数据库索引
后端
冬夜戏雪16 小时前
【java学习日记】【2025.12.7】【7/60】
java·开发语言·学习
CC.GG16 小时前
【C++】二叉搜索树
java·c++·redis
学历真的很重要16 小时前
VsCode+Roo Code+Gemini 2.5 Pro+Gemini Balance AI辅助编程环境搭建(理论上通过多个Api Key负载均衡达到无限免费Gemini 2.5 Pro)
前端·人工智能·vscode·后端·语言模型·负载均衡·ai编程