TCP、UDP协议,java网络通信基础

本文详细解析了OSI参考模型及TCP/IP协议栈的工作原理,包括各层的功能及TCP与UDP的区别。并通过实例介绍了Socket编程的具体实现。

  • OSI模型与TCP/IP协议栈
  • 端口
  • TCP  UDP
  • Socket ServerScoket DatagramSocket

OSI参考模型

OSI(Open System Interconnect),即开放式系统互联。 一般都叫OSI参考模型,体系结构标准定义了网络互连的七层框架(物理层数据链路层网络层传输层会话层表示层应用层),针对攻城狮们,我们不需要过多的去关注物理层、数据链路层,

网络层:IP地址的寻址,查询互联网中某台服务器

传输层:(TCP/UDP)实现端到端的通信

会话层: 实现端到端的之间的交互信息

表示层: 端到端的之间的交互形式

应用层: :HTTPHTTPSFTPTELNET,SSH,SMTPPOP3等。



  • TCP/IP协议栈

 wKioL1SIBJKy7q8oAAEMHfbl-0E582.jpg

wKiom1SIBAHw1MybAAE_fDStMQg817.jpg

由于OSI模型和协议比较复杂,所以并没有得到广泛的应用。

端口

端口有什么用呢?我们知道,一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等,这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP 地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区 分不同的服务的。

TCP/UDP

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠、基于字节流的输层通信协议,TCP为了保证报文传输的可靠[1]  就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。

TCP三次握手的过程如下:
  1. 客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。
  2. 服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入 SYN_RECV状态。
  3. 客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。
三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。

UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为UDP协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序



对比UDP和TCP协议的主要区别是两者在如何实现信息的可靠传递方面不同,TCP协议中包含了专门的传递保证机制,当数据接收方收到发送方传来的信息时,会自动向发送方发出确认消息;发送方只有在接收到该确认消息之后才继续传送其它信息,否则将一直等待直到收到确认信息为止。与TCP不同,UDP协议并不提供数据传送的保证机制。如果在从发送方到接收方的传递过程中出现数据报的丢失,协议本身并不能做出任何检测或提示。因此,通常人们把UDP协议称为不可靠的传输协议。TCP在现实当中就像我们打电话先拨通在说话,UDP就像是发短信

wKiom1SIBzHSMZ78AAF3CFFhIxI894.jpg

  • Socket ServerScoket DatagramSocket

TCP 套接字处理流程

UDP 套接字处理流程




--------参考资料------------

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class ClientTcp
{
    private static final String host = "localhost";
    
    private static final int port = 1999;
    
    public static void main(String[] args)
        throws IOException
    {
        Socket scoketClient = null;
        OutputStream writer = null;
        BufferedReader buffer = null;
        String readLine = null;
        try
        {
            while (true)
            {
                scoketClient = new Socket(host, port);
                writer = scoketClient.getOutputStream();
                buffer = new BufferedReader(new InputStreamReader(scoketClient.getInputStream()));
                
                int c;
                while ((c = System.in.read()) != -1)
                {
                    writer.write(c);
                    if (c == '\n')
                    {
                        writer.flush();
                        break;
                    }
                }
                System.out.println("Server:" + buffer.readLine());
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            scoketClient.close();
            writer.close();
            buffer.close();
        }
    }
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server
{
    
    static final int port = 1999;
    
    static final ExecutorService service = Executors.newFixedThreadPool(10);
    
    public static void main(String[] args)
        throws IOException
    {
        
        ServerSocket serverScoket = null;
        try
        {
            serverScoket = new ServerSocket(port);
            
            while (true)
            {
                Socket socket = serverScoket.accept();
                System.out.println(socket);
                service.submit(new Work(socket));
            }
        }
        catch (Exception e)
        {
            
            e.printStackTrace();
            
        }
        finally
        {
            serverScoket.close();
        }
    }
}

class Work implements Runnable
{
    
    Socket scoket;
    
    BufferedReader reader = null;
    
    BufferedWriter writer = null;
    
    public Work(Socket scoket)
        throws IOException
    {
        
        this.scoket = scoket;
        this.reader = new BufferedReader(new InputStreamReader(scoket.getInputStream()));
        this.writer = new BufferedWriter(new OutputStreamWriter(scoket.getOutputStream(), "UTF-8"));
        
    }
    
    @Override
    public void run()
    {
        
        String readLine = null;
        try
        {
            while ((readLine = reader.readLine()) != null)
            {
                System.out.println(readLine);
                int c;
                while ((c = System.in.read()) != -1)
                {
                    writer.write(c);
                    if (c == '\n')
                    {
                        writer.flush();
                        break;
                    }
                }
                break;
            }   
        }
        catch (IOException e)
        {
            
            e.printStackTrace();
            
        }
        finally
        {
            try
            {
                scoket.close();
                reader.close();
                writer.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
}

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class ClientUDP
{
    
    public static void main(String[] args)
        throws IOException
    {
        DatagramSocket client = null;
        try
        {
            client = new DatagramSocket();
            byte[] sendBytes = {'a', 'b', 'c'};
            byte[] recvBytes = new byte[1024];
            
            InetAddress ipAddress = InetAddress.getByName("localhost");
            DatagramPacket sendPackage = new DatagramPacket(sendBytes, sendBytes.length, ipAddress, 1999);
            client.send(sendPackage);
            
            DatagramPacket recvPackage = new DatagramPacket(recvBytes, recvBytes.length);
            client.receive(recvPackage);
            
            System.out.println(new String(recvPackage.getData(), "GBK"));
            
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            client.close();
        }
    }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ServerUDP
{
    
    public static void main(String[] args)
        throws IOException
    {
        DatagramSocket client = null;
        byte[] sendBytes = {'h', 'e', 'l'};
        byte[] recvBytes = new byte[1024];
        try
        {
            client = new DatagramSocket(1999);
            while (true)
            {
                System.out.println("服务监听。。。。。");
                DatagramPacket revc = new DatagramPacket(recvBytes, recvBytes.length);
                client.receive(revc);
                System.out.println("Recv:" + new String(revc.getData()));
                
                DatagramPacket send =
                    new DatagramPacket(sendBytes, sendBytes.length, revc.getAddress(), revc.getPort());
                client.send(send);
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            client.close();
        }
        
    }
    
}

《Java网路编程》

《百度百科》


同步定位与地图构建(SLAM)技术为移动机器人或自主载具在未知空间中的导航提供了核心支撑。借助该技术,机器人能够在探索过程中实时构建环境地图并确定自身位置。典型的SLAM流程涵盖传感器数据采集、数据处理、状态估计及地图生成等环节,其核心挑战在于有效处理定位与环境建模中的各类不确定性。 Matlab作为工程计算与数据可视化领域广泛应用的数学软件,具备丰富的内置函数与专用工具箱,尤其适用于算法开发与仿真验证。在SLAM研究方面,Matlab可用于模拟传感器输出、实现定位建图算法,并进行系统性能评估。其仿真环境能显著降低实验成本,加速算法开发与验证周期。 本次“SLAM-基于Matlab的同步定位与建图仿真实践项目”通过Matlab平台完整再现了SLAM的关键流程,包括数据采集、滤波估计、特征提取、数据关联与地图更新等核心模块。该项目不仅呈现了SLAM技术的实际应用场景,更为机器人导航与自主移动领域的研究人员提供了系统的实践参考。 项目涉及的核心技术要点主要包括:传感器模型(如激光雷达与视觉传感器)的建立与应用、特征匹配与数据关联方法、滤波器设计(如扩展卡尔曼滤波与粒子滤波)、图优化框架(如GTSAM与Ceres Solver)以及路径规划与避障策略。通过项目实践,参与者可深入掌握SLAM算法的实现原理,并提升相关算法的设计与调试能力。 该项目同时注重理论向工程实践的转化,为机器人技术领域的学习者提供了宝贵的实操经验。Matlab仿真环境将复杂的技术问题可视化与可操作化,显著降低了学习门槛,提升了学习效率与质量。 实践过程中,学习者将直面SLAM技术在实际应用中遇到的典型问题,包括传感器误差补偿、动态环境下的建图定位挑战以及计算资源优化等。这些问题的解决对推动SLAM技术的产业化应用具有重要价值。 SLAM技术在工业自动化、服务机器人、自动驾驶及无人机等领域的应用前景广阔。掌握该项技术不仅有助于提升个人专业能力,也为相关行业的技术发展提供了重要支撑。随着技术进步与应用场景的持续拓展,SLAM技术的重要性将日益凸显。 本实践项目作为综合性学习资源,为机器人技术领域的专业人员提供了深入研习SLAM技术的实践平台。通过Matlab这一高效工具,参与者能够直观理解SLAM的实现过程,掌握关键算法,并将理论知识系统应用于实际工程问题的解决之中。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值