网路编程(二)UDP和TCP协议下传输数据

本文介绍了UDP和TCP两种传输协议的特点,并通过实际代码示例展示了它们的应用场景。UDP适用于无需建立连接且对速度要求较高的场景;而TCP则适用于需要确保数据可靠传输的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UDP传输数据特点
只需要一个目的地,然后将数据一直发送就行了。类似发快递

1.将数据及源和目的封装成数据包中,不需要建立连接
2.每个数据报的大小在限制在64k内
3.因无连接,是不可靠协议
4.不需要建立连接,速度快

(DatagramSocket 和 DatagramPacket类 )

TCP传输数据特点
3次握手确认后才可以传输,类似通话

1.建立连接,形成传输数据的通道。
2.在连接中进行大数据量传输
3.通过三次握手完成连接,是可靠协议
4.必须建立连接,效率会稍低

(Socket 和 ServerSocket类)

☆TCP传输最容易出现的问题

客户端连接上服务端,两端都在等待,没有任何数据传输。
通过例程分析:
因为read方法或者readLine方法是阻塞式。
解决办法:
自定义结束标记
使用shutdownInput,shutdownOutput方法。

实例 代码实现
UDP 从一个本机的一个端口发送信息(达哥,你可以的)到另一个端口
发送类

package cn.hncu.dage.UDP;

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

/**
 * @author<a href="mailto:953801304@qq.com">胡龙华</a>
 * @version 2017-4-5  下午7:27:28
 * @fileName SendDemo.java
 */

public class SendDemo {

    public static void main(String[] args) {
        try {
            DatagramSocket ds =null;
            //1.创建一个用来发送数据包的Socket (10000表示发送的端口号)
            // 这里是封装你要发送的信息
                ds = new DatagramSocket();
                String str = "达哥,你可以的";
                byte buf [] = str.getBytes(); 
                //2.用一个数据包发发送数据,buf数据小于64K,然后要给发送的IP(机器号)以及接受软件的端口号(10001)
                DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("113.242.132.34"), 10001);
                //3.调用一个方法发送
                ds.send(dp);
            // 4.关流
            ds.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

接收类

package cn.hncu.dage.UDP;

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

/**
 * @author<a href="mailto:953801304@qq.com">胡龙华</a>
 * @version 2017-4-5  下午8:23:57
 * @fileName ReceiveDemo.java
 */
public class ReceiveDemo {

    public static void main(String[] args) {
        try {
            // 1.创建一个接收数据的Socket 接收的端口号要与前面发送数据包的端口号一致,不然别找不到
            DatagramSocket ds = new DatagramSocket(10001);
            //2. 要创建一个数据包来接? 为什么呢?
            /**
             * 在网络中传输的是字节和字符,不是前面的数据包了,所以就需要新的数据包把数据收起来
             */
            byte buf [] = new byte [1024];
            DatagramPacket dp = new DatagramPacket(buf, buf.length);
            //3.一个接收方法
            ds.receive(dp);
            //4.把接收的数据解析出来
            /**法律意识
             * 一定要追踪数据的来源地址,万一别人给你发反动信息呢? 
             * 网警抓了,你有来源地址就没事。
             */
            // 来源IP和来源端口号
            String ip = dp.getAddress().getHostAddress();
            int port = dp.getPort();
            String info = new String(dp.getData(),0,dp.getLength());
            System.out.println("Ip地址为"+ip+"发来消息如下");
            System.out.println(info);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

结果这里写图片描述

TCP 客户端发送消息到服务器,服务器发消息给客户端。就是通信
服务器代码

package cn.hncu.dage.TCP;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author<a href="mailto:953801304@qq.com">胡龙华</a>
 * @version 2017-4-5  下午8:52:16
 * @fileName MySocketSever.java
 */
public class MySocketSever {

    public static void main(String[] args) {
        // 1. 写个SeverSocket 指定端口 等待握手
        try {
            ServerSocket server = new ServerSocket(8888);
        while (true) {
            //2.握手通过一个accept() 方法可以得到发送 请求的线程
            Socket s = server.accept();
            // 读取客户端发来的信息
            InputStream in = s.getInputStream();
            byte bs[] = new byte[1024];
            in.read(bs);
            String  ip = s.getInetAddress().getHostAddress();
            System.out.println("客户端Ip为"+ip+"发来"+new String(bs));

            // 向客户端发送消息
            OutputStream out = s.getOutputStream();
            DataOutputStream dout = new DataOutputStream(out);
            dout.writeUTF("达哥,你是最棒的!!!");
            dout.close();
        }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

客户端代码

package cn.hncu.dage.TCP;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * @author<a href="mailto:953801304@qq.com">胡龙华</a>
 * @version 2017-4-5  下午9:01:50
 * @fileName MySocketClient.java
 */
public class MySocketClient {

    public static void main(String[] args) {
        try {
            Socket s = new Socket("113.242.132.34", 8888);
            // 当能向下执行的时候说明请求成功了,否则请求失败就异常了
            // 发送给服务器: 消息
            OutputStream out =s.getOutputStream();
            DataOutputStream dout = new DataOutputStream(out);
            String str = "Yes,I can";
            dout.writeUTF(str);

            //接收来自服务器的消息
            InputStream in = s.getInputStream();
            DataInputStream din = new DataInputStream(in);
            String str2 = din.readUTF();
            System.out.println("服务器说:"+str2);

            dout.close();
            din.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

结果
这里写图片描述
这里写图片描述

下面再用两个端口,一个模拟客户端,一个模拟服务器,向服务器上传一个小文件
服务器代码并启动

package cn.hncu.dage.TCP.FilePass;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class UploadTextServer {

    public static void main(String[] args) throws IOException {
        //1创建ServerSocket
        ServerSocket s = new ServerSocket(7777);
        //2获得握手方(客户端)对应的socket
        Socket sk = s.accept();
        //3读取客户端上传的文件数据----源:socket, 目的:本地磁盘
        InputStream in = sk.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(in));

        PrintWriter pw = new PrintWriter(new FileWriter("c.txt"),true);
        String str = null;
        while( (str=br.readLine())!=null){
            System.out.println("Server "+str);
            pw.println(str);         
        }

        DataOutputStream dout = new DataOutputStream(sk.getOutputStream());
        dout.writeUTF("文件上传成功");
        sk.close();
        s.close();

    }

}

客户端代码

package cn.hncu.dage.TCP.FilePass;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class UploadTextClient {

    public static void main(String[] args) throws IOException {
        Socket s = new Socket("113.242.142.12", 7777);

        BufferedReader br = new BufferedReader(new FileReader("a.txt"));

        PrintWriter pw = new PrintWriter(s.getOutputStream(),true);

        String str = null;
        while( (str=br.readLine())!=null){
        //  pw.write(str);
        //  pw.flush(); // 刷缓存啊!!!
            pw.println(str);
        }
        //★给服务器发送一个结束标记
        s.shutdownOutput();

        // 接收服务器消息
        //接收服务器的应答消息
        BufferedReader br2 = new BufferedReader( new InputStreamReader(s.getInputStream()) );
        String info = br2.readLine();
        System.out.println("server:"+info);
        s.close();

    }

}

开始只有a.txt 文件
这里写图片描述
然后 上传来了c.txt文件
这里写图片描述
对比两个文件
这里写图片描述
是完全相同的,当然,这里并不严谨没有考虑中文乱码问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值