【网络编程】TCP流套接字编程(TCP实现回显服务器)

这篇具有很好参考价值的文章主要介绍了【网络编程】TCP流套接字编程(TCP实现回显服务器)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.TCP流套字节相关API.

Socket(既能给客户端使用,也能给服务器使用)

构造方法

【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议

基本方法:

【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议

ServerSocket(只能给服务器使用)

构造方法:

【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议

基本方法:

【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议

二.TCP实现回显服务器.

客户端代码示例:

package Demo2;

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 clientSocket =null;
    public TcpEchoClient(String serverIp,int serverPort) throws IOException {
        //此处可以把这里的IP和port直接传给socket对象.
        //由于TCP是有连接的,所以socket中就会保存好这两个信息.
        clientSocket = new Socket(serverIp,serverPort);
    }
    public void start(){
        System.out.println("客户端启动~~");
        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream()
        ) {
            Scanner scannerConsole = new Scanner(System.in);
            //从控制台读取数据
            Scanner scannerNetWork = new Scanner(inputStream);
            //
            while(true){
                //1.从控制台读取数据.
                System.out.println("->");
                if(!scannerConsole.hasNext()){
                    break;
                }

                String request = scannerConsole.next();
                PrintWriter printWriter = new PrintWriter(outputStream);
                //2.把请求发送给服务器. 这里要使用println来发送.为了让发送的请求末尾带有一个换行.
                printWriter.println(request);
                //通过flush来主动刷新缓冲区,来确保数据发送到服务器了.
                printWriter.flush();
                //3.从服务器读取响应.这里也是和服务器返回响应的逻辑想对应
                String response = scannerNetWork.next();
                //4.把响应打印到控制台.
                System.out.println(response);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

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

服务器代码示例:

package Demo2;

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;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoServer {
    private ServerSocket serverSocket = null;
    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动~~");
        ExecutorService pool = Executors.newCachedThreadPool();
        while(true) {
            //通过accept方法来接听电话,然后才能进行通信.
            Socket clientSocket = serverSocket.accept();
//            Thread thread = new Thread(()->{
//                processConnection(clientSocket);
//            });
//            thread.start();
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    processConnection(clientSocket);
                }
            });
        }

    }
    //通过这个方法来处理一次连接,连接过程中就会涉及请求响应交互
    public void processConnection(Socket clientSocket){
        System.out.printf("[%s:%d] 客户端上线!\n",clientSocket.getInetAddress(),clientSocket.getPort());
        //循环读取客户端的请求并返回响应
        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream()
        ) {
            Scanner scanner = new Scanner(inputStream);
            while(true){
                //可以通过inputStream来读取数据了.
                //byte[] buffer = new byte[4096];
                //int n = inputStream.read(buffer);
                //此处读操作完全可以用read来完成,但是read是把读取到的数据放到一个byte数组之中
                //后续根据请求处理响应,还需要把数组转化成字符串.
                //此时就可以使用Scanner来简化这个过程.
                if(!scanner.hasNext()){
                    //读取完毕,例如客户端断开链接.
                    System.out.printf("[%s %d] 客户端下线!\n",clientSocket.getInetAddress(),clientSocket.getPort());
                    break;
                }
                //1.读取请求并解析,此时有一个隐藏的约定,next读的时候要读到空白符才会结束
                //  因此就要求客户端发来的请求必须带有空白符结尾.比如带有/n或" ".
                String request = scanner.next();
                //2.根据请求计算响应.
                String response = process(request);
                //3.把相应给客户端.
                //outputStream.write(response.getBytes(),0,response.getBytes().length);
                //  通过这种方式可以返回,但是这种方式不方便给返回的响应中添加换行
                //  此时就可以给outputStream套一层来完成更方便的写入.
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(response);
                printWriter.flush();
                System.out.printf("[%s %d] request : %s ;response : %s ",clientSocket.getInetAddress(),clientSocket.getPort(),request,response);
                System.out.println();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    public String process(String request){
        return request;
    }

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

运行结果:
【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议
【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议文章来源地址https://www.toymoban.com/news/detail-857365.html

代码执行流程:

  1. 服务器启动,阻塞在accept,等待客户端建立连接.
    【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议
  2. 客户端启动.这里的new操作会触发和服务器之间建立连接的操作.此时服务器就会从accept中返回.
    【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议
  3. 服务器解除阻塞,继续向下执行,执行processConnection方法
    【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议执行这个方法,执行到hasNext就会阻塞,此时虽然建立了连接,但是客户端还没有发来任何请求.hasNext阻塞等待到请求到达.
  4. 客户端继续执行到hasNext,等待用户向客户端写入内容.
    【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议
  5. 如果用户真的输入了,就会继续向下执行发送请求等待返回的逻辑.
    【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议这里就会把请求真的发出去,同时客户端等待服务器返回响应,此时next就会阻塞等待.
  6. 服务器从hasNext 返回读取到的请求,构造响应,并把响应返回给客户端.
    【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议此时服务器结束此次循环,开启下一次循环,继续阻塞在hasNext等待下一个请求
  7. 客户端读取到响应,并显示出来.
    【网络编程】TCP流套接字编程(TCP实现回显服务器),网络,tcp/ip,服务器,java,网络协议此时客户端就会结束此次循环,开启下一次循环,继续阻塞在hasNext等待用户输入下一个请求.

代码注意事项:

    1. flush()方法存在一个内存缓冲区.由于文件IO的操作比较低效,因此就希望IO的次数少一些,等攒到一定程度再进行IO操作.(相当于多次IO合并成一次了). 因此就引入了缓冲区,此时就会出现问题,你输入的数据比较少,数据被存在内存缓冲区了,所以需要我们手动刷新缓冲区.
    1. 如果客户端非常的多,就需要创建多个Socket对象,此时就可能导致系统的资源使用完了,因此需要在Socket执行完毕之后关闭资源.
    1. 引入线程池来解决频繁的创建销毁线程.
    1. 如果有多个客户端建立请求,并且长时间不销毁
    • 解决方案一:引入协程===>轻量级线程,用户态可以通过手动调度的方式让一个线程并发的做多个任务.
    • 解决方案二:IO多路复用===>这是一个系统内核级别的机制,本质上是让一个线程去处理多个Socket对象 (这些Socket数据并非是同一时刻都需要处理).

到了这里,关于【网络编程】TCP流套接字编程(TCP实现回显服务器)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 网络编程套接字( TCP )

    目录 1、实现一个TCP网络程序(单进程版)         1.1、服务端serverTcp.cc文件                  服务端创建套接字                  服务端绑定                  服务端监听                  服务端获取连接                  服务

    2024年01月17日
    浏览(36)
  • 【JavaEE】网络编程之TCP套接字、UDP套接字

    目录 1.网络编程的基本概念 1.1为什么需要网络编程  1.2服务端与用户端 1.3网络编程五元组  1.4套接字的概念 2.UDP套接字编程 2.1UDP套接字的特点  2.2UDP套接字API 2.2.1DatagramSocket类 2.2.2DatagramPacket类  2.2.3基于UDP的回显程序 2.2.4基于UDP的单词查询  3.TCP套接字编程 3.1TCP套接字的特

    2023年04月20日
    浏览(41)
  • 【JaveEE】网络编程之TCP套接字、UDP套接字

    目录 1.网络编程的基本概念 1.1为什么需要网络编程  1.2服务端与用户端 1.3网络编程五元组  1.4套接字的概念 2.UDP套接字编程 2.1UDP套接字的特点  2.2UDP套接字API 2.2.1DatagramSocket类 2.2.2DatagramPacket类  2.2.3基于UDP的回显程序 2.2.4基于UDP的单词查询  3.TCP套接字编程 3.1TCP套接字的特

    2023年04月13日
    浏览(39)
  • 【网络编程】网络编程套接字(三)TCP网络程序

    与前边的UDP网络程序相同,创建套接字的接口都是socket,下边对socket接口进行介绍: 协议家族选择AF_INET,因为我们要进行网络通信。 而第二个参数,为服务类型,传入SOCK_STREAM,我们编写TCP程序,所以要选择流式的服务。 第三个参数默认传入0,由前两个参数就可以推出这是

    2024年02月16日
    浏览(30)
  • 【Linux网络】网络编程套接字(TCP)

    目录 地址转换函数 字符串IP转整数IP 整数IP转字符串IP 关于inet_ntoa 简单的单执行流TCP网络程序 TCP socket API 详解及封装TCP socket  服务端创建套接字  服务端绑定  服务端监听  服务端获取连接  服务端处理请求 客户端创建套接字 客户端连接服务器 客户端发起请求 服务器测试

    2024年03月21日
    浏览(41)
  • 【Java】网络编程与Socket套接字、UDP编程和TCP编程实现客户端和服务端通信

    为什么需要网络编程? 现在网络普及程序越来越高,网络上保存着我们日常生活中需要的各种资源,使用程序通过网络来获取这些资源的过程就需要网络编程来实现。 什么是网络编程? 网络编程,指网络上的主机,通过不同的进程以程序的方式实现网络通信(网络数据传输)

    2024年02月17日
    浏览(43)
  • 【Linux】网络---->套接字编程(TCP)

    TCP的编程流程:大致可以分为五个过程,分别是准备过程、连接建立过程、获取新连接过程、消息收发过程和断开过程。 1.准备过程:服务端和客户端需要创建各自的套接字,除此之外服务端还需要绑定自己的地址信息和进行监听。注意:服务端调用listen函数后,处理监听状

    2024年02月04日
    浏览(34)
  • Linux网络编程——tcp套接字

    本章Gitee仓库:tcp套接字 客户端: 客户端: 关于构造和初始化,可以直接在构造的时候,将服务器初始化,那为什么还要写到 init 初始化函数里面呢? 构造尽量简单一点,不要做一些“有风险”的操作。 tcp 是面向连接的,通信之前要建立连接,服务器处于等待连接到来的

    2024年02月20日
    浏览(28)
  • 网络编程套接字之三【TCP】

    目录 1. ServerSocket API(给服务器端使用的类) 2. Socket API(既给服务器使用,也给客户端使用) 3. 写TCP回显—服务器 4. 使用线程池后的TCP服务器代码(最终) 5. 写回显-客户端 6. TCP回显—客户端代码 7. 运行回显服务器和客户端 TCP流套接字编程  ServerSocket 是创建TCP服务端Socket的

    2024年01月19日
    浏览(28)
  • [Linux] 网络编程 - 初见TCP套接字编程: 实现简单的单进程、多进程、多线程、线程池tcp服务器

    网络的上一篇文章, 我们介绍了网络变成的一些重要的概念, 以及 UDP套接字的编程演示. 还实现了一个简单更简陋的UDP公共聊天室. [Linux] 网络编程 - 初见UDP套接字编程: 网络编程部分相关概念、TCP、UDP协议基本特点、网络字节序、socket接口使用、简单的UDP网络及聊天室实现…

    2024年02月16日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包