网络协议编程——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();
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
TCP/IP 网络编程是指基于TCP/IP协议栈进行网络通信的一种编程方式。TCP/IP协议栈由四层协议组成,包括应用层、TCP/UDP层、IP层和链路层。在TCP/IP网络编程中,程序通过创建套接字(socket)来建立网络连接,使用TCPUDP协议进行数据传输。 TCP/IP的四层协议栈中,应用层负责处理应用程序与网络的交互,包括HTTP、FTP、SMTP等协议;TCP/UDP层负责处理传输层协议,其中TCP提供面向连接的可靠传输,而UDP提供无连接的不可靠传输;IP层负责处理网络层协议,将数据包从源地址传输到目标地址;链路层负责处理物理层协议,将数据转换成比特流进行传输。 在TCP/IP网络编程中,TCP套接字和UDP套接字经过的层级结构有一些差异。TCP套接字在传输层使用TCP协议,提供可靠的、面向连接的数据传输。它通过三次握手的方式建立连接,保证数据的可靠传输。UDP套接字在传输层使用UDP协议,提供无连接的、不可靠的数据传输。它不需要建立连接,直接发送数据包,适用于对传输效率要求较高的场景。 因此,在TCP/IP网络编程中,根据需求选择使用TCP套接字或UDP套接字可以实现不同的传输方式和性能表现。TCP套接字适用于对数据可靠性要求较高的场景,而UDP套接字适用于对传输效率要求较高的场景。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [TCP/IP网络编程(一)](https://blog.csdn.net/m0_45172994/article/details/130534473)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [网络编程——TCP/IP协议](https://blog.csdn.net/m0_49519243/article/details/116132413)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值