IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> udp和tcp -> 正文阅读

[网络协议]udp和tcp

udp服务器和tcp服务器.
udp服务器按照数据报的形式发送,数据包即字节数组,然后经过五层协议在网络上进行传输.
tcp服务器面向字节流,也即字符串,规定收发双发的数据必须相同,所以一般是按行读取和发送.
tcp服务器执行过程:
1.首先建立连接,通过实例化一个Socket对象(即网卡)实现.其中内核会自动通过三次握手建立连接,建立连接是保证客户端和服务器端的收发能力正常.
2.建立连接后内核将Socket放入阻塞队列,然后服务器端通过accept方法取出连接,对连接进行处理,相当于打电话,一个人和另外几个人拨通电话,然后按照这几个人的先后顺序一个一个进行通话交流,但是这种方式只能一次处理一个连接,所以用多线程并发机制可以实现多个连接并发处理.
3.处理过程包括长连接和短连接,长连接是指一个连接中会有很多次交互,一般通过循环实现,短连接是指只能有一次交互.连接终止的时候客户端会先终止,然后服务器端才会终止,服务器为客户端服务.
当客户端和服务器端在收发过程中时,如果一方没有发送数据,则另一方会阻塞,知道另一方发送数据为止.
注意:在发送后,要进行flush操作,这是因为数据发送之前放到了内存中的缓冲区里,而最终需要经过数据链路层的网卡进行发送,flush操作会将缓冲区的数据放到网卡中,由网卡给数据加上mac地址,封装成帧,然后再由物理层转换为光电信号在网络介质中进行传输.如果不进行flush操作,则数据就会一直停留在缓冲区里,不会放到网卡中.另外,udp是自动随机将寻找mac路径,但是tcp已经建立连接,不用再寻找路径,直接用之前的就可以.
用tcp服务器实现简单的回显服务器.
**tcp:**客户端:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.Buffer;

/**
 * @author :liuheizi
 * @date :Created in 2022/2/5 15:09
 * @description:TCP代码
 * @modified By:
 * @version: 1.8.0_192
 */
class EchoSever {
    private ServerSocket serverSocket=null;

    public EchoSever(int port) throws IOException {
        this.serverSocket = new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动");
        while (true) {
            Socket socket = serverSocket.accept();
            poccess(socket);
        }

    }

    public void poccess(Socket n) {
        System.out.println("客户端端口号:" + n.getInetAddress().toString());
        System.out.println("客户端端口号:" + n.getPort());
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(n.getInputStream()));
             BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(n.getOutputStream()))
        ) {
            while (true) {
                String request = bufferedReader.readLine();
                String response = poccess1(request);
                bufferedWriter.write(response+"\n");
                bufferedWriter.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("客户端退出");
        }
    }


    public String poccess1(String request) {
    return request;
    }
}
public class Mytest {
    public static void main(String[] args) throws IOException {
        EchoSever myServer = new EchoSever(9090);
        myServer.start();
    }
}

tcp客户端:

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * @author :liuheizi
 * @date :Created in 2022/2/5 15:56
 * @description:
 * @modified By:
 * @version: 1.8.0_192
 */
class EchoClient1 {
    private Socket socket;

    public EchoClient1(String serverIp, int serverPort) throws IOException {
        this.socket = new Socket(serverIp, serverPort);
    }
    public void start() {
        Scanner scanner = new Scanner(System.in);

        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
             BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
        ) {
            while (true) {
                System.out.println("请输入");
                String request = scanner.nextLine();
                if ("exit".equals(request)) {
                    break;
                }
                bufferedWriter.write(request+"\n");
                bufferedWriter.flush();
                String response=bufferedReader.readLine();
                System.out.println(response);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class MyClientTest {
    public static void main(String[] args) throws IOException {
        EchoClient1 echoClient = new EchoClient1("127.0.0.1",9090);
        echoClient.start();
    }
}

缓冲区的几种情况:
1.tcp服务器
2.文件传输(io流)
3.从控制台读取和打印

并发处理的服务器端代码:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.Buffer;

/**
 * @author :liuheizi
 * @date :Created in 2022/2/5 15:09
 * @description:TCP代码
 * @modified By:
 * @version: 1.8.0_192
 */
class EchoSever {
    private ServerSocket serverSocket=null;

    public EchoSever(int port) throws IOException {
        this.serverSocket = new ServerSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动");
        **while (true) {
            Socket socket = serverSocket.accept();
            Thread t1=new Thread(){
                @Override
                public void run() {
                    poccess(socket);
                }
            };
            t1.start();
        }** 

    }

    public void poccess(Socket n) {
        System.out.println("客户端端口号:" + n.getInetAddress().toString());
        System.out.println("客户端端口号:" + n.getPort());
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(n.getInputStream()));
             BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(n.getOutputStream()))
        ) {
            while (true) {
                String request = bufferedReader.readLine();
                String response = poccess1(request);
                bufferedWriter.write(response+"\n");
                bufferedWriter.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("客户端退出");
        }
    }


    public String poccess1(String request) {
    return request;
    }
}
public class Mytest {
    public static void main(String[] args) throws IOException {
        EchoSever myServer = new EchoSever(9090);
        myServer.start();
    }
}

实现服务器的关键是通过请求计算响应,也就是上图中的pocces1函数.
udp实现回显服务器
服务器端:

import javax.xml.crypto.Data;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * @author :liuheizi
 * @date :Created in 2022/2/5 15:56
 * @description:
 * @modified By:
 * @version: 1.8.0_192
 */
public class UdpEchoSever {
    private DatagramSocket datagramSocket;

    public UdpEchoSever(int port) throws SocketException {
        this.datagramSocket = new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动");
        while (true) {
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            datagramSocket.receive(requestPacket);
            String request = new String(requestPacket.getData(),0,requestPacket.getLength()).trim();
            String response = poccess(request);
            DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,
                    requestPacket.getSocketAddress());
            datagramSocket.send(responsePacket);
            System.out.println("客户端ip:" + requestPacket.getAddress());
            System.out.println("客户端端口号:"+requestPacket.getPort());
        }
    }
        public String poccess(String request){
            return request;
        }

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

客户端:

import javax.xml.crypto.Data;
import java.io.IOException;
import java.net.*;
import java.util.Scanner;

/**
 * @author :liuheizi
 * @date :Created in 2022/2/5 19:48
 * @description:
 * @modified By:
 * @version: 1.8.0_192
 */
public class UdpEchoClient {
   private DatagramSocket datagramSocket;
   private String severIp;
   private int severPort;

    public UdpEchoClient(String severIp, int severPort) throws SocketException {
        this.datagramSocket = new DatagramSocket();
        this.severIp=severIp;
        this.severPort = severPort;
    }
    public void start() throws IOException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("服务器启动");
        while (true) {
            System.out.println("请输入");
            String request=scanner.nextLine();
            if ("exit".equals(request)) {
                break;
            }
            DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(severIp),severPort);
            this.datagramSocket.send(requestPacket);
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            datagramSocket.receive(responsePacket);
            String response = new String(requestPacket.getData(),0,requestPacket.getLength()).trim();
            System.out.println(response);
        }
    }
    public static void main(String[] args) throws IOException {
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1", 9090);
        udpEchoClient.start();
    }

}
比较:
udp效率更高,因为不用建立连接,但是数据的安全性不高,容易丢失;tcp数据安全性高,但是效率低,因为需要需要频繁的建立连接和销毁连接.
udp代码比较繁琐,但是原理简单,即字节数组传输,tcp代码简单,但原理比较复杂,需要建立连接.
udp可以多个客户端访问,表现为哪个客户端给服务器发送数据了,服务器就接收数据并处理返回,此处是没有并发的,而不是向tcp那样一个一个客户端进行处理,tcp解决这个问题是通过并发线程.
多个客户端访问同一个服务器怎样简单实现?
通过xshell窗口,Java 包.类命令:
在这里插入图片描述
快捷键:shift加右键
TCP中的连接代表客户端和服务器都具有收发能力,但是得保证客户端或者服务器端成功将数据封装成帧,然后在网络上传输,若在封装成数据帧之前出了问题,则该端就发送不成功.

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-02-06 14:07:32  更:2022-02-06 14:07:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/5 11:19:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码