UDP协议编程

TCP/UDP编程

对网络协议最常用的基础知识点的回忆

基础知识点详解:

第一个基础知识就是OSI模型的展示:

osi一直在说,今天来看看osi(open System Interconncetion,OSI/RM,Open System Interconnection Reference Modle):

OSI模型,即开放式通信系统互联参考模型(Open System Interconnection,OSI/RM,Open Systems Interconnection Reference Model),是国际标准化组织(ISO)提出的一个试图使各种计算机在世界范围内互连为网络的标准框架,简称OSI。

注意这几个缩写 ios(苹果公司的移动操作系统); iso(国际标准化组织) OSI(osi模型)

OSI将计算机网络体系结构(architecture)划分为以下七层;这也就是我们常说的osi七层协议:

下面的是百度百科关于各层的说明(通俗易懂)
  • 物理层(Physical Layer): 将数据转换为可通过物理介质传送的电子信号 相当于邮局中的搬运工人

  • 数据链路层(Datalink Layer): 决定访问网络介质的方式在此层将数据分帧,并处理流控制。本层指定拓扑结构并提供硬件寻址。相当于邮局中的装拆箱工人

  • 网络层(Network Layer): 使用权数据路由经过大型网络 相当于邮局中的排序工人(ip协议)

  • 传输层(Transport Layer): 提供终端到终端的可靠连接 相当于公司中跑邮局的送信职员

  • 会话层(Session Layer): 允许用户使用简单易记的名称建立连接 相当于公司中收寄信、写信封与拆信封的秘书

  • 表示层(Presentation Layer): 协商数据交换格式 相当公司中简报老板、替老板写信的助理

  • 应用层(Appliication Layer): 用户的应用程序和网络之间的接口老板

数据传输

数据包的概念: 数据包是一个信息单位,作为一个整体,从网络中的一个设备传送给另一个设备。

数据包是在应用层创建的,从上向下一层一层的传递,每一层对数据包重新的组装.

数据包的格式:

  1. 数据包结构

数据包包含了几种不同类型的数据:

- 信息,某种类的计算机控制数据和命令

  • 会话控制代码

  • 数据包头

  • 数据

  • 报尾

    1. 创建数据包

数据包的创建过程是从OSI模型的应用层开始的。跨网络传输的信息要从应用层开始,往下依次穿过各层。每层都对数据包进行重新组装,以增加自己的信息(信头)。

TCP/UDP的缩写(在传输层上(第四层))

TCP(Transmission Control Protocol,传输控制协议):

UDP( User Datagram Protocol 用户数据报协议),在网络中它与TCP协议一样用于处理数据包。在OSI模型中,在第四层——传输层,处于IP协议的上一层。

IP协议: IP (Internet Protocol),处于网络层上(第三层)

网络层:

网络层负责对子网间的数据包进行路由选择。网络层还可以实现拥塞控制、网际互连等功能。

在这一层,数据的单位称为数据包(packet)。网络层协议的代表包括:IP、IPX、RIP、OSPF、ARP、RARP、ICMP、IGMP等。

传输层:

传输层是第一个端到端,即主机到主机的层次。传输层负责将上层数据分段并提供端到端的、可靠的或不可靠的传输。此外,传输层还要处理端到端的差错控制和流量控制问题。

在这一层,数据的单位称为数据段(segment)。传输层协议的代表包括:TCP、UDP、SPX等。

应用层:

应用层为操作系统或网络应用程序提供访问网络服务的接口。应用层协议的代表包括:Telnet、FTP、HTTP、SNMP等。

什么是TCP和UDP

TCP和UDP协议的区别(面试中经常问到):

  • UDP
    • 面向无连接,数据不安全,速度快。不区分客户端与服务端。
  • TCP
      * 面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。
    • 三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据

在这里在说说sockect(套接字)

  • 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
    • 通信的两端都有Socket。
    • 网络通信其实就是Socket间的通信。
    • 数据在两个Socket间通过IO流传输。
    • Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和port。

UDP传输

DatagramSocket类用来创建和发送UDP的Socket实例;

DatagramSocket():创建实例。通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。

DatagramSocket(int port):创建实例,并固定监听Port端口的报文。

DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文

receive(DatagramPacket d):接收数据报文到d中。receive方法产生一个“阻塞”。

send(DatagramPacket d):发送报文d到目的地。

setSoTimeout(int timeout):设置超时时间,单位为毫秒。

close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Sock

DatagramPacket:用于处理报文,将byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成byte数组。

DatagramPacket(byte[] buf, int length, InetAddress addr, int port):从buf数组中,取出length长的数据创建数据包对象,目标是addr地址,port端口。

DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):从buf数组中,取出offset开始的、length长的数据创建数据包对象,目标是addr地址,port端口。

DatagramPacket(byte[] buf, int offset, int length):将数据包中从offset开始、length长的数据装进buf数组。

DatagramPacket(byte[] buf, int length):将数据包中length长的数据装进buf数组。

getData():它从实例中取得报文的byte数组编码。

  • 1.发送Send
    • 创建DatagramSocket, 随机端口号
    • 创建DatagramPacket, 指定数据, 长度, 地址, 端口
    • 使用DatagramSocket发送DatagramPacket
    • 关闭DatagramSocket
  • 2.接收Receive
    • 创建DatagramSocket, 指定端口号
    • 创建DatagramPacket, 指定数组, 长度
    • 使用DatagramSocket接收DatagramPacket
    • 关闭DatagramSocket
    • 从DatagramPacket中获取数据
  • 3.接收方获取ip和端口号
    • String ip = packet.getAddress().getHostAddress();
    • int port = packet.getPort();

发送端的java代码:

package com.heima.socket;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class Demo1_Send {
/**
 * * 1.发送Send
 * 创建DatagramSocket, 随机端口号
 * 创建DatagramPacket, 指定数据, 长度, 地址, 端口
 * 使用DatagramSocket发送DatagramPacket
 * 关闭DatagramSocket
 * @throws SocketException 
 * @throws UnknownHostException 
 */
public static void main(String[] args) throws Exception {
    String str = "what are you 弄啥呢?";
    DatagramSocket socket = new DatagramSocket();               //创建Socket相当于创建码头
    //InetAddress.getByName("127.0.0.1"):要发给谁,要写对方的ip地址
    DatagramPacket packet =                                     //创建Packet相当于集装箱,,存放要发送的数据
            new DatagramPacket(str.getBytes(), str.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
    socket.send(packet);                                        //发货,将数据发出去
    socket.close();                                             //关闭码头
}
}

UDP传输的接收端:

package com.heima.socket;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Demo1_Receive {
/**
 ** 2.接收Receive
 * 创建DatagramSocket, 指定端口号
 * 创建DatagramPacket, 指定数组, 长度
 * 使用DatagramSocket接收DatagramPacket
 * 关闭DatagramSocket
 * 从DatagramPacket中获取数据
 * @throws Exception 
 */
public static void main(String[] args) throws Exception {
    DatagramSocket socket = new DatagramSocket(6666);       //创建Socket相当于创建码头
    DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//创建Packet相当于创建集装箱
    socket.receive(packet);                                 //接货,接收数据

    byte[] arr = packet.getData();                          //获取数据
    int len = packet.getLength();                           //获取有效的字节个数
    System.out.println(new String(arr,0,len));
    socket.close();
}
}

对上面的代码进行优化:

发送端优化代码展示:

package com.heima.socket;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
public class Demo2_Send {
/**
 * * 1.发送Send
 * 创建DatagramSocket, 随机端口号
 * 创建DatagramPacket, 指定数据, 长度, 地址, 端口
 * 使用DatagramSocket发送DatagramPacket
 * 关闭DatagramSocket
 * @throws SocketException 
 * @throws UnknownHostException 
 */
public static void main(String[] args) throws Exception {
    Scanner sc = new Scanner(System.in);                        //创建键盘录入对象
    DatagramSocket socket = new DatagramSocket();               //创建Socket相当于创建码头

    while(true) {
        String line = sc.nextLine();                            //获取键盘录入的字符串
        if("quit".equals(line)) {
            break;
        }
        DatagramPacket packet =                                 //创建Packet相当于集装箱
                new DatagramPacket(line.getBytes(), line.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);
        socket.send(packet);                                    //发货,将数据发出去
    }
    socket.close();                                             //关闭码头
}
}

接收端代码优化展示:

package com.heima.socket;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Demo2_Receive {
/**
 ** 2.接收Receive
 * 创建DatagramSocket, 指定端口号
 * 创建DatagramPacket, 指定数组, 长度
 * 使用DatagramSocket接收DatagramPacket
 * 关闭DatagramSocket
 * 从DatagramPacket中获取数据
 * @throws Exception 
 */
public static void main(String[] args) throws Exception {
    DatagramSocket socket = new DatagramSocket(6666);       //创建Socket相当于创建码头
    DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);//创建Packet相当于创建集装箱

    while(true) {
        socket.receive(packet);                                 //接货,接收数据

        byte[] arr = packet.getData();                          //获取数据
        int len = packet.getLength();                           //获取有效的字节个数
        String ip = packet.getAddress().getHostAddress();       //获取ip地址
        int port = packet.getPort();                            //获取端口号
        System.out.println(ip + ":" + port + ":" + new String(arr,0,len));
    }
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值