J2SE网络编程之 TCP与UDP

1.什么是TCP

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

  • 客户端向服务端发送请求报文;
  • 服务端收到后向客户端回复;
  • 客户端确认收到服务端的回复。

三次握手完成后,客户端就与服务端建立了可靠的链接。

2.什么是UDP

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

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

3.TCP Socket示例

服务端示例:

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();
        }
    }
}

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

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

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

4.UDP示例

服务端Demo

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();
    }
}

客户端Demo

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();
    }
}

整个流程如下图:


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

5.总结

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

时间: 2024-08-05 11:14:58

J2SE网络编程之 TCP与UDP的相关文章

应聘复习基础笔记1:网络编程之TCP与UDP的优缺点,TCP三次握手、四次挥手、传输窗口控制、存在问题

重要性:必考 一.TCP与UDP的优缺点 ①TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端的可靠传输.对可靠性要求较高的应用层协议,如FTP.Telnet.SMTP.HTTP.POP3 ②UDP---用户数据报协议,是一个简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去

Java网络编程之TCP、UDP

Java网络编程提供了两种协议:TCP(传输控制协议)和UDP(数据报协议).TCP(Transmission Control Protocol)是一种可靠的传输协议,传输时会采用"三次握手"端的方式建立连接,以保证数据的可靠性和安全性:而UDP(User Datagram Protocol)协议是一种不可靠的传输协议,发送的数据不一定能够接受的到,网上的聊天是工具一般采用的此协议.下面将详细的接受TCP和UDP的使用以及相应的编码. 一.TCP网络通信 Java中使用Socket(套

网络编程之TCP/IP各层详解

网络编程之TCP/IP各层详解 我们将应用层,表示层,会话层并作应用层,从TCP/IP五层协议的角度来阐述每层的由来与功能,搞清楚了每层的主要协议,就理解了整个物联网通信的原理. 首先,用户感知到的只是最上面一层--应用层,自上而下每层都依赖于下一层,所以我们从最下层开始切入,比较好理解. 每层都运行特定的协议,越往上越靠近用户,越往下越靠近硬件. 一.物理层 由来:孤立的计算机之间要一起"玩耍",就必须接入Internet,即计算机之间必须完成组网. 物理层功能:主要是基于电器特性发

java网络编程之TCP实例

Dgram类 package Socket; import java.net.DatagramPacket; import java.net.InetAddress; public class Dgram { public static DatagramPacket toDatagram(String s, InetAddress destIA, int destPort) { byte[] buf = new byte[s.length() + 1]; s.getBytes(0, s.leng

扯谈网络编程之Tcp SYN flood洪水攻击

简介 TCP协议要经过三次握手才能建立连接: (from wiki) 于是出现了对于握手过程进行的攻击.攻击者发送大量的FIN包,服务器回应(SYN+ACK)包,但是攻击者不回应ACK包,这样的话,服务器不知道(SYN+ACK)是否发送成功,默认情况下会重试5次(tcp_syn_retries).这样的话,对于服务器的内存,带宽都有很大的消耗.攻击者如果处于公网,可以伪造IP的话,对于服务器就很难根据IP来判断攻击者,给防护带来很大的困难. 攻与防 攻击者角度 从攻击者的角度来看,有两个地方可以

linux网络编程之TCP/IP基础篇(一)

从今天起,将会接触到网络编程,平台是linux,实现语言C语言,最后将会实现一个简易的miniftp服务器. 主要的内容安排为:linux网络编程之TCP/IP基础篇,SOCKET编程篇,进程间通信篇,线程篇,实战ftp篇. 1.ISO/OSI参考模型:open system interconnection开放系统互联模型是由OSI(international organization for standardization )国际标准化组织定义的网络分层模型,共七层. 各层的具体含义: 物理层

网络编程之TCP编程

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption

【Unity3D自学记录】网络编程之TCP&UDP的区别

TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接.一个TCP连接必须要经过三次"对话"才能建立起来,其中的过程非常复杂,我们这里只做简单.形象的介绍,你只要做到能够理解这个过程即可.我们来看看这三次对话的简单过程:主机A向主机B发出连接请求数据包:"我想给你发数据,可以吗?",这是第一次对话:主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在

网络编程之TCP/UDP及其流程比较(转)

TCP与UDP的区别 基于连接与无连接 对系统资源的要求(TCP较多,UDP少) UDP程序结构较简单 流模式与数据报模式TCP保证数据正确性,UDP可能丢包TCP保证数据顺序,UDP不保证 具体编程时的区别 socket()的参数不同 UDP Server不需要调用listen和accept UDP收发数据用sendto/recvfrom函数 TCP:地址信息在connect/accept时确定UDP:在sendto/recvfrom函数中每次均 需指定地址信息 UDP:shutdown函数无