网络协议编程——TCP/UDP


一、TCP编程

1、客户端发送信息给服务端,服务端将数据显示在控制台上

客户端:

package TcpDemo1;

import jdk.net.Sockets;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;

public class TcpClient {
    
    
    public static void main(String[] args)  {
    
    
        Socket socket = null;
        OutputStream os = null;
        try {
    
    
            //连接到服务器的地址
            InetAddress serverIP = InetAddress.getByName("127.0.0.1");
            int port = 8899;
            //创建一个socket
            socket = new Socket(serverIP,port);
            //创建一个输出流,往外写东西
            os = socket.getOutputStream();
            os.write("你好".getBytes(StandardCharsets.UTF_8));
        } catch (UnknownHostException e) {
    
    
            e.printStackTrace();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }finally{
    
    
            //关闭资源
            try{
    
    
                if(os!=null){
    
    
                    os.close();
                }
                if(socket!=null){
    
    
                    socket.close();
                }
            }catch(IOException e) {
    
    
                e.printStackTrace();
            }
        }


    }
}

服务器:

package TcpDemo1;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.FileAlreadyExistsException;

public class TcpServer {
    
    
    public static void main(String[] args) {
    
    
        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
    
    
            //开放服务器端口
            serverSocket = new ServerSocket(8899);
            //等待客户端连接
            accept = serverSocket.accept();
            //读入客户端的信息
            is = accept.getInputStream();

            //管道流
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while((len=is.read(buffer))!=-1){
    
    
                baos.write(buffer,0,len);
            }

            System.out.println(baos.toString());
            System.out.println(accept.getInetAddress().getHostName());
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            try{
    
    
                if(baos!=null){
    
    
                    baos.close();
                }
                if(is!=null){
    
    
                    is.close();
                }
                if(accept!=null){
    
    
                    accept.close();
                }
                if(serverSocket!=null){
    
    
                    serverSocket.close();
                }
            }catch(Exception e){
    
    
                e.printStackTrace();
            }
        }
    }
}

2、客户端发送文件给服务器,服务端将文件保存在本地

客户端:

package TcpDemp2;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class TcpClient {
    
    
    public static void main(String[] args) {
    
    

        try {
    
    
            //创建socket连接
            Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),8899);
            //创建一个输出流
            OutputStream os = socket.getOutputStream();
            //读取文件
            FileInputStream fis = new FileInputStream(new File("fan.jpg"));
            //写出文件
            byte[] buffer = new byte[1024];
            int len;
            while((len = fis.read(buffer))!=-1){
    
    
                os.write(buffer,0,len);
            }

            //告诉服务器已经传输完成,关闭数据的输出,不然就会一直阻塞
            socket.shutdownOutput();

            //等待服务器的响应并输出的控制台
            InputStream inputStream = socket.getInputStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer2 = new byte[1024];
            int len2;
            while((len2 = inputStream.read(buffer2))!=-1){
    
    
                baos.write(buffer2,0,len2);
            }
            System.out.println(baos.toString());

            //关闭资源
            fis.close();
            os.close();
            socket.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}


服务器:

package TcpDemp2;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class TcpServer {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //开启ServerSocket
        ServerSocket serverSocket = new ServerSocket(8899);
        //监听客户端
        Socket accept = serverSocket.accept();
        //获取输入流
        InputStream is = accept.getInputStream();
        //读取文件并保存
        FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer))!=-1){
    
    
            fos.write(buffer,0,len);
        }

        //通知客户端接收成功
        OutputStream outputStream = accept.getOutputStream();
        outputStream.write("文件已经传输完成".getBytes(StandardCharsets.UTF_8));

        //关闭资源
        fos.close();
        is.close();
        accept.close();
        serverSocket.close();
    }
}

二、UDP编程

  • DatagramSocket 和 DatagramPacket 两个类实现了基于UDP协议的网络程序。
  • UDP 数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不确定什么时候可以抵达。
  • DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。
  • UDP协议中每个数据报都给出了完整的地址信息,因此无需建立发送方和接收方的连接

1、发送方给接收方发消息

发送方:

package UdpDemo1;

import javafx.scene.chart.PieChart;

import java.io.IOException;
import java.net.*;
import java.nio.channels.DatagramChannel;
import java.nio.charset.StandardCharsets;

public class UdpClient {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //建立DatagramSocket
        DatagramSocket socket = new DatagramSocket();
        //封装数据包
        String msg = "UDPSender=>";
        byte[] data = msg.getBytes();
        InetAddress inet = InetAddress.getByName("127.0.0.1");
        int port = 9090;
        DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,port);

        //通过socket发送packet
        socket.send(packet);

        //关闭
        socket.close();
    }
}

接收方:

package UdpDemo1;

import javafx.scene.chart.PieChart;

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

public class UdpServer {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //建立DatagramSocket 开放端口
        DatagramSocket socket = new DatagramSocket(9090);

        //接受数据
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
        socket.receive(packet);

        //输出数据
        System.out.println(new String(packet.getData(),0,packet.getLength()));

        //关闭
        socket.close();
    }
}

2、连续发送多个消息

发送端:

package UdpDemo2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class UdpSender {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //使用DatagramSocket指定端口创建发送端
        DatagramSocket socket = new DatagramSocket(8888);
        //准备数据,转成字节数组
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        while(true){
    
    
            String data = reader.readLine();
            byte[] datas = data.getBytes(StandardCharsets.UTF_8);
            //封装成为数据包
            DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));

            //发送包裹
            socket.send(packet);

            //退出判断
            if(data.equals("bye")){
    
    
                break;
            }
        }
        
        socket.close();
    }
}

接收方:

package UdpDemo2;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpReceiver {
    
    
    public static void main(String[] args) throws Exception {
    
    
        DatagramSocket socket = new DatagramSocket(6666);
        while(true){
    
    
            try{
    
    
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                socket.receive(packet);//阻塞式接收包裹

                byte[] datas = packet.getData();
                int len = packet.getLength();
                String data = new String(datas,0,len);
                System.out.println(data);

                //退出判断
                if(data.equals("bye")){
    
    
                    break;
                }
            }catch (Exception e){
    
    
                e.printStackTrace();
            }
        }
        socket.close();
    }
}

おすすめ

転載: blog.csdn.net/weixin_46025531/article/details/123970319