TCP和UDP的使用

TCP与UDP区别总结:

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付

3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的

UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)

4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

5、TCP首部开销20字节;UDP的首部开销小,只有8个字节

6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

socket结构:

1. 端口只是一个数字辨识,不是真正的物理端口; 
2. 一个Socket连接的主键(即不同socket之间的区分)是由一个五元组{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL}组成,即{源地址,源端口,目标地址,目标端口,协议}组成,那些说四元组不包含协议的说法是错误的。 

一般客户端创建socket不需要去bind端口和ip,socket所在进程会自动分配一个为占用的端口和进程的所在ip,就是上面的SRC-IP, SRC-PORT。

DEST-IP, DEST-PORT这个是客户端需要连接目标服务器填写的目标服务器的ip和端口

服务端这边需要bind本机的端口,然后accept收到客户端的连接,会去创建一个新的socket,五元组{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL}填写完整,更具不同的SRC-IP, SRC-PORT源IP和端口来区分来自不同客户端,更具DEST-PORT, PROTOCOL宿ip和宿端口来区分是不是本机的哪个端口处理。
3. 一个进程可以拥有多个socket连接。

TCp的编写

客户端 :需要创建一个连接的Socket ,需要写入目标服务器的ip和端口。(这里的ip和端口是指服务器对外映射的ip和端口)

服务器端:需要开启监听本地端口,然后重监听的端口里accept 根据不同的源ip和端口,创建出不同客户端来源的socket请求,生成对应的socket来接受信息。

 

例子一、两个客户端连接在同个服务器的同个端口80,即有两个socket连接: 
- socket1 {SRC-A, 100, DEST-X,80, TCP} 
- socket2{SRC-B, 100, DEST-X,80, TCP} 
主机A和主机B的地址不同,两台主机同时连接到服务器X的80端口。服务器要怎么处理这个连接是它的事,我们要理解的是为什么一个主机同个端口能监听多个客户端Socket连接。

解释: 
1. 是因为两个客户端的IP不同,服务器能识别出不同的Socket; 
2. 即使IP地址相同,端口不同,服务器也能够分辨; 
3. 只要服务器知道收到的请求和哪个socket相关,那么它就能使用这个socket正确地回复那个客户端; 
4. 如果对于不同的socket需要不同的端口,那么不仅仅浪费服务器资源,而且每次客户端连接上serverSocket之后还要另外分配新的端口和客户端通信。没必要。

例子二、不同的进程可以监听同一个端口。

  1. 因此在服务器的两个使用不同协议的进程可以监听同一个端口。
  2. 如果一个socket的辨识只是四元组不包括协议{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT},那么不同进程是不可能同时监听同一个端口的。没有协议的话一个客户端连接到同一台某个有两个进程监听端口的服务器,那么就没有什么机制可以确定客户端是要连接哪一个进程了。

两个不同的客户端(一个使用tcp一个用udp)可以连接同一个服务器的同一个端口,但是需要两个不同的服务器进程。

我觉得是错的,所以我尝试了一下:

服务器:

    public static void main(String[] args) throws IOException {
        //很明显如下程序在同一个进程

        //udp使用5555端口
        DatagramSocket ds = new DatagramSocket(5555);
        byte[] buf = new byte[1024];
        DatagramPacket dp_receive = new DatagramPacket(buf, 1024);
        ds.receive(dp_receive);
        System.out.println("收到udp消息");
        System.out.println("客户端发送udp端口为" + dp_receive.getPort());

        //tcp使用5555端口
        ServerSocket serverSocket = new ServerSocket(5555);
        Socket socket = serverSocket.accept();
        System.out.println("tcp建立了连接");
        System.out.println("客户端发送tcp端口为" + socket.getPort());

    }

客户端:

服务器输出:

收到udp消息
客户端发送udp端口为12345
tcp建立了连接
客户端发送tcp端口为12345

所以很明显,同个进程也可以通过不同的协议监听同一个端口。


总结

  1. 不同协议可以监听同一个端口(不管是不是在服务器的同个进程)
  2. 某个协议的进程可以监听多个客户端的连接,因为只要五元组不同进程就能分辨。
  3. 从上面的例子可以知道,客户端同个进程也可以在同个端口用不同的协议与客户端建立连接。

你可能感兴趣的:(TCP和udp)