当前位置:   article > 正文

【计算机网络之TCP协议与UDP协议详解】_局域网是属于tcp还是udp

局域网是属于tcp还是udp

网络相关

按区域分为:

  • 局域网(区域小,如:一个房间、一栋楼)
  • 城域网(区域稍大,如:城市、省份)
  • 广域网(最大,如:国家、地球)

Internet国际互联网就是最常用的广域网

按层次分为:

从下到上分为:

​ 1) 物理层,底层硬件

​ 2) 数据链路层,通信的介质

​ 3) 网络层,寻址和路由, IP协议

​ 4) 传输层,连接和数据通信,TCP协议\UDP协议

​ 5) 会话层,管理会话

​ 6) 表示层,处理数据格式、加密

​ 7) 应用层,程序之间的通信,http协议\ftp协议\smtp协议\pop3协议

在这里插入图片描述

IP协议

Internet Protocol 网际协议

用于在网络中定义计算机的位置

分为:

  • ipv4 由四个数字(0~255)组成,如: 192.168.223.223

    本质是32位二进制数 10101000 11110101 10110011 11100111

  • ipv6

端口

计算机上每个程序的数据通信的入口

不同的应用程序可以通过端口区分:3306、6379、8080、22122…

1~65535之间

TCP协议

Transfer Control Protocol 传输控制协议

主要控制点对点之间数据的通信

三大特点:

  1. 面向字节流的
  2. 面向连接的(两个点之间需要一直保持连接)
  3. 可靠的

三次握手

TCP可靠性基于三次握手

点对点通信前通过三次握手建立连接

在这里插入图片描述

1) 客户端向服务端发送报文,标志位SYN(同步请求),seq(序列号)给服务器,客户端进入SYN_SENT(请求发送)状态

2) 服务端接收了客户端的报文,进入SYN_RCVD(同步接收)状态,然后发送报文SYN(同步),ACK(应答),ack(应答序列号),seq(序列号)给客户端

3) 客户端收到服务端的报文进入Established(连接建立),发送应答报文ACK,ack给服务端,服务端进入Established状态,双方建立连接

四次挥手

点对点断开连接需要进行四次挥手

在这里插入图片描述

1) 客户端向服务端发送结束报文FIN,进入等待状态1

2) 服务端收到结束报文后,进入等待关闭状态,发送应答报文ack

3) 客户端接收服务端的应答报文ack,进入等待状态2

4) 服务端释放资源后,发送结束FIN给客户端,进入LAST_ACK状态

5) 客户端收到服务端的结束报文,发送应答报文ACK给服务端,连接关闭

Socket编程

套接字,基于TCP/IP协议

服务端

ServerSocket 类 ,服务端Socket

创建方法:

new ServerSocket(端口号)
  • 1

ServerSocket创建后会自动对这个端口号进行侦听

常用方法:

Socket accept()		接收客户端的连接,并返回客户端连接对象,会自动阻塞线程直到有客户端连接
void disconnect()   关闭连接
  • 1
  • 2

客户端

Socket类,客户端Socket

创建方法:

new Socket(服务端IP,服务端PORT)
  • 1

创建Socket对象后,就向服务端发送连接请求

常用方法:

InetAddress getInetAddress() 获得地址
void setTimeout(long) 设置超时时间
OutputStream getOutputStream() 获得输出流
InputStream getInputStream() 获得输入流
  • 1
  • 2
  • 3
  • 4

注意:任意的IO流关闭后,socket自动关闭

/**
 * 服务端
 */
public class MyServer {

    public static final int PORT = 8888;

    //启动服务器
    public void start(){
        System.out.println("服务器启动了");
        //创建ServerSocket对象
        try(ServerSocket serverSocket = new ServerSocket(PORT)){
            while(true){
                //获得客户端的连接
                Socket socket = serverSocket.accept();
                System.out.println("接收到客户端:" + socket.getInetAddress());
                //读取客户端的信息
                try(ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())){
                    String str = ois.readUTF();
                    System.out.println(socket.getInetAddress()+"说:" + str);
                    //给客户端发送消息
                    oos.writeUTF("客户端你好,现在时间:" + new Date());
                    oos.flush();
                }catch (IOException ex){
                    ex.printStackTrace();
                }
            }
        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new MyServer().start();
    }
}

/**
 * 客户端
 */
public class MyClient {

    //连接服务端,并发送文字
    public void connect(String ip,int port,String msg){
        //创建Socket对象
        try(Socket socket = new Socket(ip,port);
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());){
            //向服务端发文字
            oos.writeUTF(msg);
            oos.flush();
            //接收服务端的消息
            String s = ois.readUTF();
            System.out.println("服务端说:" + s);
        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new MyClient().connect("192.168.110.30",8888,"服务器你好啊!");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

实现文件传输

在这里插入图片描述

客户端:

  1. 创建文件输入流
  2. 创建Socket,通过Socket对象获得输出流
  3. 循环,一边从文件读取字节,一边向网络输出流写出字节

服务端:

  1. 创建文件输出流
  2. 通过ServerSocket获得Socket
  3. 通过Socket获得输入流
  4. 循环,一边从网络输入流读取字节,一边写到文件输出流中
/**
 * 文件客户端
 */
public class FileClient {

    //发送文件
    public void sendFile(String ip,int port,String path){
        File file = new File(path);
        //创建文件输入流
        try(FileInputStream in = new FileInputStream(path);
            //创建socket
            Socket socket = new Socket(ip,port);
            //获得输入流
            ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream())
            ){
            //发文件名
            out.writeUTF(file.getName());
            out.flush();
            //发文件
            int len = -1;
            byte[] buff = new byte[1024];
            //循环,一边读,一边写
            while((len = in.read(buff)) != -1){
                out.write(buff,0,len);
            }
        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new FileClient().sendFile("127.0.0.1",9999,"D:\\install\\Git-2.8.3-64-bit.exe");
    }
}

/**
 * 文件服务端
 */
public class FileServer {

    public static final String DIR = "D:\\files\\";

    //启动服务
    public void start(){
        try(ServerSocket serverSocket = new ServerSocket(9999)){
            while(true){
                Socket accept = serverSocket.accept();
                //网络输入流
                try(ObjectInputStream in = new ObjectInputStream(accept.getInputStream())){
                    //接收文件名
                    String fileName = in.readUTF();
                    File file = new File(DIR + fileName);
                    //接收文件
                    //文件输出流
                    FileOutputStream out = new FileOutputStream(file);
                    int len = -1;
                    byte[] buff = new byte[1024];
                    //循环,一边读,一边写
                    while((len = in.read(buff)) != -1){
                        out.write(buff,0,len);
                    }
                    out.close();
                    System.out.println(accept.getInetAddress()+"上传完毕:"+ file.getName());
                }
            }
        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new FileServer().start();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

UDP协议

UDP是数据报协议,类似于广播,不需要三次握手来创建连接,传输数据速度快但是不可靠

TCP和UDP的区别

UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输可靠传输
连接个数支持一对一,一对多,多对多通信只能是一对一通信
传输方式面向报文面向字节流
适用场景适用于实时应用(IP电话、视频会议、直播等)适用于要求可靠传输的应用,例如文件传输

UDP编程

DatagramSocket 可以做UDP的客户端也可以做服务器端

创建方法:

服务器端
new DatagramSocket(端口号)	
客户端
new DatagramSocket()	 
  • 1
  • 2
  • 3
  • 4

主要方法:

send(DatagramPacket) 发送数据包
receive(DatagramPacket) 接收数据包
  • 1
  • 2

DatagramPacket UDP数据包,用于接收和发送数据

创建方法:

用于接收数据的数据包
DatagramPacket(byte[] 数据字节 ,int 数据长度)
用于发送数据的数据包
DatagramPacket(byte[] 数据字节 ,int 数据长度,InetAddress 地址,int 端口)
  • 1
  • 2
  • 3
  • 4

常用方法:

byte[] getData() 获得数据
  • 1
/**
 * UDP服务端
 */
public class UdpServer {

    public static final int PORT = 9999;

    public void start(){
        System.out.println("启动UDP服务端!");
        //创建udp socket对象
        try(DatagramSocket server = new DatagramSocket(PORT)){
            //创建数据包
            byte[] data = new byte[1024];
            DatagramPacket packet = new DatagramPacket(data,
                    data.length);
            //接收数据
            server.receive(packet);
            //输出
            System.out.println(packet.getAddress()+"说:"+
                    new String(packet.getData(),
                            0,packet.getLength(),
                            "UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new UdpServer().start();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
public class UdpClient {

    public void sendMsg(String ip,int port,String msg){
        //创建客户端socket
        try(DatagramSocket client = new DatagramSocket()){
            //创建数据包
            byte[] bytes = msg.getBytes("UTF-8");
            DatagramPacket packet = new DatagramPacket(
                    bytes,bytes.length,
                    InetAddress.getByName(ip),port);
            //发送数据
            client.send(packet);
            System.out.println("发送完毕");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new UdpClient().sendMsg("192.168.110.21",9999,"你好!UDP");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/585065
推荐阅读
相关标签
  

闽ICP备14008679号