【J2SE快速进阶】——Socket编程入门(TCP/UDP)

简介: 作品展时,我们的作品 “超级飞聊” 的主打功能就是聊天,包括局域网聊天、外网聊天等,虽然那时是用VB实现的(winsock控件),不过每种编程中的思想还是大同小异的,所以学习Java中的Socket编程时,倍感亲切啊。

      概念了解

      Socket又称“套接字”,用来向网络中的主机发出请求或者应答网络中发出的请求。


      文章开头先来简单了解一下TCP与UDP这两个协议:


      TCP


      TCP(Transmission Control Protocol传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,位于传输层。这三个特点中,面向连接就如同打电话,双方的电话必须保持连接状态才能通话;可靠就如同QQ上的视频,一方发送视频请求,另一方必须同意后才能建立视频连接,也可以说安全性好;基于字节流,继续看下文就行。


      TCP最重要的思想就是大名鼎鼎的“三次握手”:


86.png

86.png


      客户端向服务端发送请求报文,服务端收到后向客户端回复,客户端确认收到服务端的回复。三次握手完成后,客户端就与服务端建立了可靠的链接。


     

       UDP


       UDP(User Datagram Protocol用户数据报协议),提供简单但不可靠的信息传送服务。很像生活中的写信或发邮件,不需要征得对方的同意,不需要与对方建立连接,就可以将数据发送出去,但是不能保证发送出去的数据能够确保无误地到达目的地。



      我们常用的ping命令就是基于UDP协议,telnet命令就是基于TCP协议。


      记得在VB中使用winsock,先往窗体上拖两个winsock控件(相当于实例化),然后给它们设置IP、端口、传输协议,就可以通信了。只不过在Java中,基于TCP协议的通信需要用ServerSocket和Socket来完成,基于UDP协议的通信需要用 DatagramSocket和DatagramPacket来完成。

      下面从TCP和UDP两个方面来举例说明Java中如何进行网络通信。    


       基于TCP协议的通信    

       服务端代码:      

import java.io.*;
import java.net.*;
public class Server { 
  public static void main(String[] args) {
    InputStream is=null; 
    OutputStream os=null;
    try{
      ServerSocket ss=new ServerSocket(5566);         //创建服务器套接字并绑定到5566端口
      Socket s=ss.accept();
      is=s.getInputStream();
      os=s.getOutputStream();
      DataInputStream dis=new DataInputStream(is);
      DataOutputStream dos=new DataOutputStream(os);
      String message=null;
      if((message=dis.readUTF())!=null){              //接收并输出此连接的客户端发来的信息
        System.out.println("Client:"+message);
      }
      dos.writeUTF("Hello, Client!");                //向此连接的客户端发送信息
      dis.close();
      dos.close();
      s.close();
    }catch(ConnectException ex){
      ex.printStackTrace();
    }catch(IOException ex){
      ex.printStackTrace();
    }
  }
}


       客户端代码:

import java.io.*;
import java.net.*;
public class Client {
  public static void main(String[] args) {
    InputStream is=null;
    OutputStream os=null;
    try{
      Socket s=new Socket("127.0.0.1",5566);         //创建一个套接字并将其连接到127.0.0.1地址(本机)的5566端口
      is=s.getInputStream();
      os=s.getOutputStream();
      DataInputStream dis=new DataInputStream(is);
      DataOutputStream dos=new DataOutputStream(os);
      dos.writeUTF("Hello, Server!");               //向服务端发送信息
      String message=null;
      if((message=dis.readUTF())!=null){
        System.out.println("Server:"+message);    //接收并输出服务端发来的信息
      }
      dis.close();
      dos.close();
      s.close();      
    }catch(ConnectException ex){
      ex.printStackTrace();
    }catch(IOException ex){
      ex.printStackTrace();
    }
  }
}


    执行结果:


         客户端: 87.png      

               服务端:88.png


       整个连接和交互的过程如下图:

89.png


       执行时,先启动服务端,服务端创建服务器套接字ServerSocket并绑定到指定的端口,当执行到Socket s=ss.accept()时,会产生“阻塞”(即让程序暂时停留在此处),但客户端启动,创建套接字Socket并向指定地址的指定端口发送请求时,ServerSocket接受服务端的请求并返回客户端的socket实例,与之建立连接。socket原意为插座,还真的挺形象的,整个过程就如同把客户端的插头插到服务端的插座上,就建立起了通道。通信完毕后,双方都关闭连接。


       例子中,Socket的getInputStream()方法可以获得网络连接输入,返回此套接字的字节输入流对象;getOutputStream()方法返回此套接字的字节输出流对象,用于向连接对象写入数据。这里体现了上文中TCP的第三个特点“基于字节流”。


       基于UDP协议的通信


       服务端代码:    

import java.net.*;
class UDPServer{
    public static void main(String[] args)throws Exception{
      //接收信息
        DatagramSocket  server = new DatagramSocket(5050);
        byte[] recvBuf = new byte[1000];
        DatagramPacket recvPacket = new DatagramPacket(recvBuf , recvBuf.length);
        server.receive(recvPacket);
        String recvStr = new String(recvPacket.getData() , 0 , recvPacket.getLength());
        System.out.println("What server has received is:" + recvStr);
        //发送信息
        int port = recvPacket.getPort();
        InetAddress addr = recvPacket.getAddress();
        String sendStr = "Hello ! I'm Server";
        byte[] sendBuf = new String("Hello Client! I'm Server!").getBytes();    
        DatagramPacket sendPacket 
            = new DatagramPacket(sendBuf , sendBuf.length , addr , port );
        server.send(sendPacket);
        server.close();
    }
}


      客户端代码:


import java.net.*;
class UDPClient{
    public static void main(String[] args)throws Exception{
      //发送信息
        DatagramSocket client = new DatagramSocket();       
        byte[] sendBuf=new String("Hello Server! I'm Client").getBytes();       
        InetAddress addr = InetAddress.getByName("127.0.0.1");
        int port = 5050;
        DatagramPacket sendPacket 
            = new DatagramPacket(sendBuf ,sendBuf.length , InetAddress.getByName("127.0.0.1") , port);
        client.send(sendPacket);
        //接收信息
        byte[] recvBuf = new byte[100];
        DatagramPacket recvPacket = new DatagramPacket(recvBuf , recvBuf.length);
        client.receive(recvPacket);
        String recvStr = new String(recvPacket.getData() , 0 ,recvPacket.getLength());
        System.out.println("What client has received is:" + recvStr);
        client.close();
    }
}


       整个流程如下图:

90.png

       服务端启动后,准备一个包含字节数组buf的数据报包DatagramPacket用于接收客户端发来的数据报,客户端启动后,将目的地址、端口、发送内容等信息封装在DatagramPacket中,通过DatagramSocket的send()方法发往目的地(服务端),服务端将接收到的数据报放在DatagramPackage中。服务端向客户端发送数据报的过程亦然。




      文章前面说了TCP三次握手,客户端发送请求、服务端接受请求并返回确认信息,客户端收到确认信息后再发送确认收到确认信息,简单的三个步骤,过程却非常复杂(而且TCP断开连接时还需要四次挥手)。因为UDP协议不需要连接的过程,所以它的效率高,速度快,同时也因如此,UDP的可靠性不如TCP高。


相关文章
|
8月前
|
网络协议 安全 网络安全
什么是TCP/UDP/HTTP?它们如何影响你的内网穿透体验?
数据的传输离不开各种协议,它们就像现实世界中的交通规则,规定了数据如何打包、寻址、传输和接收。对于使用内网穿透的用户来说,理解TCP、UDP和HTTP这些基础协议的特点,能帮助你更好地理解其性能表现,并选择最适合的配置方案。
|
10月前
|
网络协议 API
区分TCP/IP、HTTP、Socket三者的差异
HTTP关注于应用层的协议规范,而Socket关注于为应用程序提供编程中的网络功能,这些功能本身是建立在底层的TCP/IP协议之上;HTTP是更高层次的抽象,定义了如何包装数据,而TCP/IP定义了如何传送数据,Socket则是两者之间在程序中的桥梁,负责实现细节。在实际应用中,通常HTTP通信也是通过Socket来完成,因为HTTP仅是具体内容的封装形式,而Socket则是传送方式的实现形式。
929 16
|
10月前
|
网络协议 安全 网络安全
详细阐述 TCP、UDP、ICMPv4 和 ICMPv6 协议-以及防火墙端口原理优雅草卓伊凡
详细阐述 TCP、UDP、ICMPv4 和 ICMPv6 协议-以及防火墙端口原理优雅草卓伊凡
675 2
|
10月前
|
网络协议 安全 API
WebSocket、Socket、TCP 和 HTTP 的差别与应用场景
WebSocket、Socket、TCP 和 HTTP 是网络通信中的四大“使者”,各具特色:HTTP 适合短时请求,TCP 稳定可靠,Socket 灵活定制,WebSocket 实现实时双向通信。本文用通俗语言解析它们的区别与应用场景,助你为项目选择最合适的通信方式。
3147 3
|
网络协议 Java 开发工具
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
706 1
|
监控 网络协议 网络性能优化
不再困惑!一文搞懂TCP与UDP的所有区别
本文介绍网络基础中TCP与UDP的区别及其应用场景。TCP是面向连接、可靠传输的协议,适用于HTTP、FTP等需要保证数据完整性的场景;UDP是无连接、不可靠但速度快的协议,适合DNS、RIP等对实时性要求高的应用。文章通过对比两者在连接方式、可靠性、速度、流量控制和数据包大小等方面的差异,帮助读者理解其各自特点与适用场景。
|
存储 网络协议 安全
用于 syslog 收集的协议:TCP、UDP、RELP
系统日志是从Linux/Unix设备及网络设备生成的日志,可通过syslog服务器集中管理。日志传输支持UDP、TCP和RELP协议。UDP无连接且不可靠,不推荐使用;TCP可靠,常用于rsyslog和syslog-ng;RELP提供可靠传输和反向确认。集中管理日志有助于故障排除和安全审计,EventLog Analyzer等工具可自动收集、解析和分析日志。
1226 2
|
监控 网络协议 网络性能优化
网络通信的核心选择:TCP与UDP协议深度解析
在网络通信领域,TCP(传输控制协议)和UDP(用户数据报协议)是两种基础且截然不同的传输层协议。它们各自的特点和适用场景对于网络工程师和开发者来说至关重要。本文将深入探讨TCP和UDP的核心区别,并分析它们在实际应用中的选择依据。
822 3
|
机器学习/深度学习 人工智能 网络协议
TCP/IP五层(或四层)模型,IP和TCP到底在哪层?
TCP/IP五层(或四层)模型,IP和TCP到底在哪层?
635 4
|
域名解析 网络协议
IP协议, TCP协议 和DNS 服务分别是干什么的?
大家好,我是阿萨。昨天讲解了网络四层协议[TCP/IP协议族分为哪4层?]今天我们学习下IP 协议, TCP 协议和DNS 协议分别是干什么的。
669 0
IP协议, TCP协议 和DNS 服务分别是干什么的?