【计算机网络之TCP协议与UDP协议详解】

文章目录

  • 网络相关
  • TCP协议
    • 三次握手
    • 四次挥手
  • Socket编程
    • 服务端
    • 客户端
    • 实现文件传输
  • UDP协议
    • TCP和UDP的区别
    • UDP编程

网络相关

按区域分为:

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

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

按层次分为:

从下到上分为:

​ 1) 物理层,底层硬件

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

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

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

​ 5) 会话层,管理会话

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

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

【计算机网络之TCP协议与UDP协议详解】_第1张图片

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可靠性基于三次握手

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

【计算机网络之TCP协议与UDP协议详解】_第2张图片

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

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

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

四次挥手

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

【计算机网络之TCP协议与UDP协议详解】_第3张图片

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

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

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

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

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

Socket编程

套接字,基于TCP/IP协议

服务端

ServerSocket 类 ,服务端Socket

创建方法:

new ServerSocket(端口号)

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

常用方法:

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

客户端

Socket类,客户端Socket

创建方法:

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

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

常用方法:

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

注意:任意的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,"服务器你好啊!");
    }
}

实现文件传输

【计算机网络之TCP协议与UDP协议详解】_第4张图片

客户端:

  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();
    }
}

UDP协议

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

TCP和UDP的区别

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

UDP编程

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

创建方法:

服务器端
new DatagramSocket(端口号)	
客户端
new DatagramSocket()	 

主要方法:

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

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

创建方法:

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

常用方法:

byte[] getData() 获得数据
/**
 * 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();
    }
}
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");
    }
}

你可能感兴趣的:(计算机网络,JAVA技术分享,tcp/ip,udp,网络,网络协议,java)