网络基础编程:TCP协议

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 网络基础编程:TCP协议

一:TCP协议基础知识

a:TCP协议提供API的两个核心类

ServerSocket 产生服务器的端口号
Socket 既能产生服务器的端口号,也能产生客户端的端口号

b:对于TCP协议的连接解析

在前面学习的过程中,我们学习到传输层的TCP协议是有连接的,即服务器和客户端进行连接.接下来,我将进行进一步的解释说明:

1):服务器有一个,而客户端有多个.且服务器和客户端之间连接代表服务器保存客户端的信息,客户端保存服务器的信息

  2):客户端有多个,服务器有一个,在内核中,客户端和服务器的已经建立好的连接很多,应用程序在应用这些连接的时候,得一个一个进行处理.此时,内核就相当于队列,所建立的连接就相当于一个一个的待办事项.

  3):TCP的连接相当于多线程学过的生产者-消费者模型,一边生产一边进行消费.

     示意图如下:

   ①:当客户端和服务器尝试建立连接的时候,此时,服务器和客户端便会产生一系列的数据交互,这个称为"握手".

    ②:等"握手"这个过程完之后,此时,socket对象便会产生"管理连接"的队列,将客户端和服务器建立好的连接加入到队列中.

    ③:由应用程序从队列取一个一个的连接,即处理一个一个的待办事项.由socket对象调用accept这个静态方法,进行消费队列中的连接

二:TCP协议提供的API的静态方法和回显服务器

a:accept静态方法

b:回显服务器

服务器代码:
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;
    private ExecutorService service= Executors.newCachedThreadPool();
    //在创建socket的同时,创建端口号
    public TcpEchoServer(int port) throws IOException {
        serverSocket=new ServerSocket(port);
    }
    //启动服务器
    public void start() throws IOException {
        System.out.println("启动服务器!");
        while(true){
            //1:处理客户端的连接,由于TCP是有连接的,服务器保存客户端的信息,客户端保存服务器的连接
            Socket clientSocket = serverSocket.accept();
            //通过上面产生的Socket对象和对方进行网络通信
//            Thread t=new Thread(()->{
//                try {
//                    processConnection(clientSocket);
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            });
//            t.start();
            service.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        processConnection(clientSocket);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }
    //通过这个方法来处理一个连接的逻辑
    public void processConnection(Socket clientSocket) throws IOException {
        //通过这两个方法获取客户端的IP地址和端口号
        System.out.printf("[%s:%d] 客户端上线!\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
        //接下来就可以读取请求,根据请求计算响应,返回响应三步走
        //Socket对象内部包含了两个字节流对象,就可以把这俩字节流对象获取到,完成后续的读写工作
        try(InputStream inputStream=clientSocket.getInputStream();
            OutputStream outputStream=clientSocket.getOutputStream();){
            //一次连接中,可能会涉及到多次请求.响应
            while(true){
                //1:读取请求并解析,为了读取方便,使用Scanner
                Scanner scanner=new Scanner(inputStream);
                if(!scanner.hasNext()){
                    //读取完毕,客户端下线
                    System.out.printf("[%s:%d] 客户端下线!\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
                    break;
                }
                //客户端发过来的请求,是文本数据,同时,还得带有空白符  next:代表一直读,一直读到空白符(换行/回车/空格/制表符/翻页符)结束
                String  request=scanner.next();
                //2.根据请求计算响应
                String response = process(request);
                //3.把响应返回给客户端,
                PrintWriter writer=new PrintWriter(outputStream);
                //此处使用PrintWriter的println方法,把响应返回给客户端
                writer.println(response);
                writer.flush();//刷新缓冲区,提高程序的效率
                //日志:打印请求详情
                System.out.printf("[%s:%d] req:%s,resp:%s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            clientSocket.close();
        }
    }
   public String process(String request){
        return request;
   }
    public static void main(String[] args) throws IOException {
       TcpEchoServer tcpEchoServer=new TcpEchoServer(9090);
       tcpEchoServer.start();
    }
}

TCP协议的回显服务器的服务器代码与UDP协议有部分区别,在TCP回显服务器的服务器代码中,主要分为连接+服务器代码必须步骤,下面,我将对TCP服务器端代码进行进一步详解,有问题的可以在底下留言.

  a:创建服务器对象

 

  b:手动设定服务器端口号

   

   c:启动服务器,即创建start方法,让服务器启动

      启动服务器,对当前日志进行打印

 

 

    d:客户端和服务器进行连接,调用ServerSocket对象的accept方法

   

           在前面的学习中,我们对于accept方法做出了详细的介绍,通过服务器的对象调用反悔了一个新的对象,小编认为返回的这个对象储存的是客户端的信息,包括客户端的IP地址和端口号.

  e:利用process方法对于客户端信息进行处理

 

processConnection方法内部代码解析:

1:读取从客户端发来的请求,服务端进行进一步解析

 2:根据第一步得到的字符解析,计算响应.
3:把响应返回给客户端

                                                    *****注意******

                          服务端是关闭客户端socket连接:防止资源的浪费

客户端代码
public class TcpEchoClient {
    private Socket socket=null;
    public TcpEchoClient(String serverIp,int serverport) throws IOException {
        //与完成了TCP客户端的建立,此时客户端通过new获得服务器的IP地址和端口号
        socket=new Socket(serverIp,serverport);
    }
    public void start(){
        System.out.println("客户端启动");
        Scanner scannerConsole=new Scanner(System.in);
        try(InputStream inputStream=socket.getInputStream();
            OutputStream outputStream=socket.getOutputStream()) {
            while(true){
              //1:从控制台输入一个字符串
                System.out.println("->");
                String request=scannerConsole.next();
              //2:构造请求,发送给服务器-->利用printWriter进行包装,将输出的进行打包,同时将从控制台输入的传递给服务器
                PrintWriter printWriter=new PrintWriter(outputStream);
                //使用println带上换行,后续服务器读取请求,就可以使用scanner.next来获取了
                printWriter.println(request);
                printWriter.flush();
                //3:从服务器读取响应,并进行处理
                Scanner scannerNetwork=new Scanner(inputStream);
                String respnse= scannerNetwork.next();
                //4:打印响应
                System.out.println(respnse);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws IOException {
      TcpEchoClient tcpEchoClient=new TcpEchoClient("127.0.0.1",9090);
      tcpEchoClient.start();
    }
}
1):客户端核心代码前准备

2):从控制台输入一个字符串

 

3):将从控制台输入的信息发送给服务器

4):从服务器读取响应,并进行打印

 


                                                ******注意*******

为了实现多客户端在同一服务器一起运行,并且互相不影响.此时我们需要多线程在服务器上来进行处理.

同时为了避免服务器的多次创建/销毁,所以我们可以利用线程池来解决.进一步节省了空间和时间.

 

 

 

相关文章
|
2天前
|
数据采集 存储 JSON
从零到一构建网络爬虫帝国:HTTP协议+Python requests库深度解析
在网络数据的海洋中,网络爬虫遵循HTTP协议,穿梭于互联网各处,收集宝贵信息。本文将从零开始,使用Python的requests库,深入解析HTTP协议,助你构建自己的网络爬虫帝国。首先介绍HTTP协议基础,包括请求与响应结构;然后详细介绍requests库的安装与使用,演示如何发送GET和POST请求并处理响应;最后概述爬虫构建流程及挑战,帮助你逐步掌握核心技术,畅游数据海洋。
15 3
|
7天前
|
数据采集 网络协议 API
HTTP协议大揭秘!Python requests库实战,让网络请求变得简单高效
【9月更文挑战第13天】在数字化时代,互联网成为信息传输的核心平台,HTTP协议作为基石,定义了客户端与服务器间的数据传输规则。直接处理HTTP请求复杂繁琐,但Python的`requests`库提供了一个简洁强大的接口,简化了这一过程。HTTP协议采用请求与响应模式,无状态且结构化设计,使其能灵活处理各种数据交换。
36 8
|
6天前
|
网络协议
UDP协议在网络通信中的独特应用与优势
UDP(用户数据报协议)作为关键的传输层协议,在网络通信中展现出独特优势。本文探讨UDP的无连接性及低开销特性,使其在实时性要求高的场景如视频流、在线游戏中表现优异;其不保证可靠交付的特性赋予应用程序自定义传输策略的灵活性;面向报文的高效处理能力及短小的包头设计进一步提升了数据传输效率。总之,UDP适用于高速、实时性强且对可靠性要求不高的应用场景,为网络通信提供了多样化的选择。
|
7天前
|
网络协议 网络架构 数据格式
TCP/IP基础:工作原理、协议栈与网络层
TCP/IP(传输控制协议/互联网协议)是互联网通信的基础协议,支持数据传输和网络连接。本文详细阐述了其工作原理、协议栈构成及网络层功能。TCP/IP采用客户端/服务器模型,通过四个层次——应用层、传输层、网络层和数据链路层,确保数据可靠传输。网络层负责IP寻址、路由选择、分片重组及数据包传输,是TCP/IP的核心部分。理解TCP/IP有助于深入掌握互联网底层机制。
33 2
|
16天前
|
网络协议 C语言
C语言 网络编程(十三)并发的TCP服务端-以进程完成功能
这段代码实现了一个基于TCP协议的多进程并发服务端和客户端程序。服务端通过创建子进程来处理多个客户端连接,解决了粘包问题,并支持不定长数据传输。客户端则循环发送数据并接收服务端回传的信息,同样处理了粘包问题。程序通过自定义的数据长度前缀确保了数据的完整性和准确性。
|
16天前
|
网络协议 C语言
C语言 网络编程(十一)TCP通信创建流程---服务端
在服务器流程中,新增了绑定IP地址与端口号、建立监听队列及接受连接并创建新文件描述符等步骤。`bind`函数用于绑定IP地址与端口,`listen`函数建立监听队列并设置监听状态,`accept`函数则接受连接请求并创建新的文件描述符用于数据传输。套接字状态包括关闭(CLOSED)、同步发送(SYN-SENT)、同步接收(SYN-RECEIVE)和已建立连接(ESTABLISHED)。示例代码展示了TCP服务端程序如何初始化socket、绑定地址、监听连接请求以及接收和发送数据。
|
16天前
|
网络协议 C语言
C语言 网络编程(十四)并发的TCP服务端-以线程完成功能
这段代码实现了一个基于TCP协议的多线程服务器和客户端程序,服务器端通过为每个客户端创建独立的线程来处理并发请求,解决了粘包问题并支持不定长数据传输。服务器监听在IP地址`172.17.140.183`的`8080`端口上,接收客户端发来的数据,并将接收到的消息添加“-回传”后返回给客户端。客户端则可以循环输入并发送数据,同时接收服务器回传的信息。当输入“exit”时,客户端会结束与服务器的通信并关闭连接。
|
16天前
|
网络协议 C语言
C语言 网络编程(十二)TCP通信创建-粘包
TCP通信中的“粘包”现象指的是由于协议特性,发送方的数据包被拆分并在接收方按序组装,导致多个数据包粘连或单个数据包分割。为避免粘包,可采用定长数据包或先传送数据长度再传送数据的方式。示例代码展示了通过在发送前添加数据长度信息,并在接收时先读取长度后读取数据的具体实现方法。此方案适用于长度不固定的数据传输场景。
|
1天前
|
Python
HTTP协议不再是迷!Python网络请求实战,带你走进网络世界的奥秘
本文介绍了HTTP协议,它是互联网信息传递的核心。作为客户端与服务器通信的基础,HTTP请求包括请求行、头和体三部分。通过Python的`requests`库,我们可以轻松实现HTTP请求。本文将指导你安装`requests`库,并通过实战示例演示如何发送GET和POST请求。无论你是想获取网页内容还是提交表单数据,都能通过简单的代码实现。希望本文能帮助你在Python网络请求的道路上迈出坚实的一步。
8 0
|
13天前
|
网络协议
网络协议概览:HTTP、UDP、TCP与IP
理解这些基本的网络协议对于任何网络专业人员都是至关重要的,它们不仅是网络通信的基础,也是构建更复杂网络服务和应用的基石。网络技术的不断发展可能会带来新的协议和标准,但这些基本协议的核心概念和原理将继续是理解和创新网络技术的关键。
28 0