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

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

相关推荐
忆挽篱笙歌3 小时前
通信连接,匿名管道
linux·服务器·网络
脚本自动化开发4 小时前
玩影之刃零,两张四千元级显卡怎么挑
后端
Pniubi6 小时前
怎么排查慢SQL,怎么解决?
java·数据库·sql
薛之谦_7 小时前
Java 全栈知识体系:从 IDEA 高效开发到 JVM、并发与 Stream 实战
java·jvm·intellij-idea
用户47949283569157 小时前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
九英里路8 小时前
protobuf快速上手
网络·c++·中间件·json·谷歌·序列化·protobuf
努力的小雨9 小时前
别再复制日志给AI了!我让Codex自己去观测云查报错
后端
afumu10 小时前
Go 写一个只监听 127.0.0.1 的控制服务:鉴权、白名单、危险命令拦截
后端·安全·go
文丑颜不良啊11 小时前
LeetCode2761~2780题目解析
java·leetcode
johnjincaaaa11 小时前
猿人学第 18 题「jsvmp 洞察先机」逆向通关实录
javascript·后端