2022-08-11 Java网络编程(网络通信)

相关概念

网络通信

两台设备之间通过网络实现数据传输
网络通信:将数据通过网络从一台设备传输到另一台设备
  • TCP:TCP(英语:Transmission Control Protocol,传输控制协议) 是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP 层是位于 IP 层之上,应用层之下的中间层。TCP 保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP。
  • UDP:UDP (英语:User Datagram Protocol,用户数据报协议),位于 OSI 模型的传输层。一个无连接的协议。提供了应用程序之间要发送数据的数据报。由于UDP缺乏可靠性且属于无连接协议,所以应用程序通常必须容许一些丢失、错误或重复的数据包。

Socket

基于客户端的网络通信,底层使用的是TCP|IP协议,套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。
当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信。java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。

  • 服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。
  • 服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。
  • 服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求连接。
  • Socket 类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够与服务器进行通信。
  • 在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket
连接建立后,通过使用 I/O 流在进行通信,每一个socket都有一个输出流和一个输入流,客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。
TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送.以下是一些类提供的一套完整的有用的方法来实现 socket。

TCP与UDP对比

简单来说就是:
TCP 发送数据前建立连接,过程中反复确认,靠谱
UDP 不建立连接,不确认,不靠谱

主要区别

两者在如何实现信息的可靠传递方面不同,UDP协议并不提供数据传送的保证机制。
如果在传递过程中出现数据包的丢失,协议本身并不能做出任何检测或提示。

TCP 具有高可靠性,确保传输数据的正确性,不出现丢失或乱序;

  1. 传输数据前是否建立连接:
    UDP 在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,
    所以会出现分组丢失、重复、乱序,应用程序需要负责传输可靠性方面的所有工作
    TCP 会建立连接,可靠,确保传输数据的正确性,不出现丢失或乱序;
  2. TCP 是面向连接的传输控制协议;
    UDP 提供了无连接的数据报服务;

    /* 客户端:发送数据,接受服务器反馈 */
    public static void main(String[] args) throws IOException {
     System.out.println("客户端发送数据");
     // 1.Socket(ip,port)确定连接到哪里
     Socket socket = new Socket("localhost",6666);
     // 2.获取流对象,输出流
     OutputStream os = socket.getOutputStream();
     // 3.组装数据
     os.write("你好 TCP,我来了".getBytes());
     System.out.println("========接收并回写==========");
     // 4.通过Socket,获取输入流对象
     InputStream in = socket.getInputStream();
     // 5.读写数据
     byte[] b = new byte[100];
     int len = in.read(b);
     System.out.println(new String(b,0,len));
     // 6.关闭资源
     in.close();
     os.close();
     socket.close();
    }
    
    /* 服务器:收到消息后给出反馈 */
    public static void main(String[] args) throws IOException {
     System.out.println("服务器端启动,等待连接.....");
     // 1.创建ServerSocket对象,绑定端口,开始等待连接
     ServerSocket ss=new ServerSocket(6666);
     // 2.接收accept方法,返回的是Socket对象
     Socket serverSocket=ss.accept();
     // 3.通过socket获取输入流
     InputStream is=serverSocket.getInputStream();
     // 4.一次性读取数据
     // 4.1创建了字节数组
     byte[] b=new byte[1024];
     // 4.2 将数据读取到字节数组中
     int len=is.read(b);
     // 4.3 解析数组,打印字符串信息
     String msg=new String(b,0,len);
     System.out.println(msg);
     System.out.println("===========回写数据==============");
     // 5 通过socket获取输出流
     OutputStream out= serverSocket.getOutputStream();
     // 6.回写数据
     out.write("我很好,谢谢你".getBytes());
     // 7.关闭资源
     is.close();
     ss.close();
    }
    

3.UDP 实时性好,工作效率较 TCP 协议高;UDP 段结构比 TCP 的段结构简单,因此网络开销也小
TCP 协议可以保证接收端毫无差错地接收到发送端发出的字节流,为应用程序提供可靠的通信服务。对可靠性要求高的通信系统往往使用 TCP 传输数据

/* 发送方 */
public static void main(String[] args) throws IOException {
    // 创建发送端Socket对象(DatagramSocet)
    DatagramSocket socket = new DatagramSocket();
    // 创建要发送数据
    byte[] bys = "hello,UDP,我来了".getBytes();
    // 创建数据,并把数据打包
    // DatagramPacket(byte[] buf, int length, InetAddress address, int po
    // 构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。
    DatagramPacket dp =
        new DatagramPacket(bys,
                           bys.length,
                           InetAddress.getByName("127.0.0.1"),
                           12345);
    // 释放资源
    socket.send(dp);
    socket.close();
}



/* 接收方 */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        //接收端和发送端端口号必须一致
        DatagramSocket ds=new DatagramSocket(12345);
        while (true){
        //创建一个数据包
        byte[] bys=new byte[1024];
        DatagramPacket dp=new DatagramPacket(bys,bys.length);
        //调用DatagramSocket对象方法接收
        ds.receive(dp);
            //解析数据包,并把数据在控制台显示输出
        System.out.println("数据是:"+new String(dp.getData()));
    }
}    

案例

编写一个服务器端和一个客户端,服务器端在9999端口,客户端连接到服务器端,服务器端接收到信息 退出

服务端类

ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("9999等待连接");
//当没有客户端连接9999端口时,程序会阻塞,等待连接
//如果有客户端连接,则会返回socket对象,程序继续
Socket socket = serverSocket.accept();
//通过socket.getInputStream()读取客户端写入到数据通道的数据
InputStream inputStream = socket.getInputStranm();
//IO读取
byte[] buf = new byte[1024];
int readLen = 0;
while((readLen = inputStream.read(buf)) != -1){
    System.out.println(new String(buf,0,readLen));//显示内容
}
//关闭流和socket
inputStream.close();
socket.close();
serverSocket.close();

客户端类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值