十、TCP、UDP协议

目录

一、TCP(传输控制协议)

二、TCP中服务端和客户端之间发送和接收

1、服务端和客户端一对一发送和接收数据,代码案例:

2、客户端-服务端-客户端传输数据,代码案例:

3、服务端接收客户端发送的文件,并保存

4、服务端与客户端以16进制收发数据

四、UDP (用户数据报协议)

五、TCP与UDP的区别


一、TCP(传输控制协议)

  • 都是位于传输层的协议
  • TCP是面向连接的,UDP是无连接的
  • TCP协议有序、安全可靠、不容易丢包
  • TCP是可靠的,UDP是不可靠的
  • TCP是面向字节流的,UDP是面向数据报文的
  • TCP只支持点对点通信,UDP支持一对一,一对多,多对多
  • TCP报文首部20个字节,UDP首部8个字节
  • TCP有拥塞控制机制,UDP没有
  • TCP协议下双方发送接受缓冲区都有,UDP并无实际意义上的发送缓冲区,但是存在接受缓冲区
  • 例子:TCP(聊天、传输文件)

二、TCP中服务端和客户端之间发送和接收

1、服务端和客户端一对一发送和接收数据,代码案例:

namespace TCPStudy1
{
   internal class Program
   {
       private static Encoding encoding = Encoding.GetEncoding("gb2312");
       private static Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
       //private static Socket sClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
       private static Socket sClient = null;

       private static Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
       static void Main(string[] args)
       {
           while (true)
           {
               Console.WriteLine("ss:启动服务端,sc:启动客户端,cs:关闭服务端,cc:关闭客户端");
               string str = Console.ReadLine();
               if (str == "ss")
               {
                   //服务端
                   StartServer();
               }
               else if (str == "sc")
               {
                   //客户端
                   StartClient();
               }
               else if (str == "cs") //关闭服务端
               {
                   s.Close();
                   if (sClient != null) 
                   {
                       sClient.Close();
                   }
               } 
               else if (str == "cc") //关闭客户端
               {
                   c.Close();
               }
               else 
               {
                   Console.WriteLine("该指令不存在");
               }
           }
           Console.ReadLine();
       }

        
       /// <summary>
       /// 服务端
       /// </summary>
       public static void StartServer() 
       {
           //Socket:C#提供的一个用于通信协议的类库,其中包含TCP协议的开发
           //TCP:服务器端
           //实例化一个TCP协议的Socket对象
           //Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
           //给服务器绑定地址和端口:192.168.218.20:6000
           IPAddress ip = IPAddress.Parse("192.168.22.1");
           IPEndPoint ipPoint = new IPEndPoint(ip, 6000);
           //把Ip和端口绑定到Socket里面
           s.Bind(ipPoint);
           //监听
           s.Listen(100);
           Console.WriteLine("=====================TCP服务端启动成功===================");
           Task.Run(() =>
           {
               while (true)//循环等待客户端连接
               {
                   //会等待客户端连接,会卡在这里,不往下运行了,直到有一个宽带连接才会继续往下运行
                   //当有客户端连接的时候,会返回客户端的连接对象
                    sClient = s.Accept();
                   Console.WriteLine("客户端请求连接了我,连接成功");
                   //讲字符串转换成byte数组

                   byte[] bytes = encoding.GetBytes("你今天吃饭了吗");
                   //给客户端发送数据
                   sClient.Send(bytes);
                   Task.Run(() => //支持多个连接本身
                   {
                       try
                       {
                           while (true)//循环接收数据
                           {
                               //接收数据
                               byte[] byteGet = new byte[1024];
                               //返回接收到的数据的大小,接收数据也会卡住,只有接收到数据的时候才会继续往下运行
                               int length = sClient.Receive(byteGet);
                               if (length == 0)
                               {
                                   Console.WriteLine("一个客户端断开了连接");
                                   return;
                               }
                               //将接收到的数据转换成字符串
                               string str = encoding.GetString(byteGet, 0, length);
                               Console.WriteLine(str);
                           }
                       }
                       catch (Exception ex)
                       {
                           Console.WriteLine("出现了异常" + ex.Message);
                       }
                       finally
                       {
                           //释放客户端资源
                           sClient.Close();
                       }
                   });
               }
           });
       }

       /// <summary>
       /// 客户端
       /// </summary>
       public static void StartClient() 
       {
           //Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
           //服务端的地址和端口
           IPEndPoint ip = new IPEndPoint(IPAddress.Parse("192.168.22.1"),6000);
           try 
           {
               //连接远程服务端
               c.Connect(ip);
               Console.WriteLine("=====================客户端连接服务端成功=====================");
           } 
           catch(Exception ex) 
           {
               Console.WriteLine("连接异常:"+ex.ToString());
               return;
           }
            
           //循环接收数据
           Task.Run(() =>
           {
               try
               {
                   while (true)
                   {
                       byte[] bytesGet = new byte[1024];
                       //等待接收对方发送的数据,返回数据的长度
                       int length = c.Receive(bytesGet);
                       string str = encoding.GetString(bytesGet, 0, length);
                       Console.WriteLine("接收的数据:" + str);
                   }
               }
               catch (Exception ex)
               {
                   Console.WriteLine("发生了错误" + ex.Message);
               }
               finally 
               {
                   //关闭连接
                   c.Close();
               }

           });
           //循环发送数据
           Task.Run(() =>
           {
               try
               {
                   int num = 1;
                   while (true)
                   {
                       //等待一秒种
                       await Task.Delay(2000);
                       byte[] bytesGo = encoding.GetBytes("我是客户端" + num);
                       //发送数据
                       c.Send(bytesGo);
                       num++; 
                   }
               }
               catch (Exception ex)
               {
                   Console.WriteLine("发生了错误" + ex.Message);
               }
               finally 
               {
                   //关闭连接
                   c.Close();
               }
           });
       }
   }
}

2、客户端-服务端-客户端传输数据,代码案例:

开启一个服务端后,可以去程序的bin\Debug目录下,双击程序的.exe文件开启多个客户端。多个客户端之间通过服务端进行收发数据

namespace TcpServer
{
    internal class Program
    {
        private static Encoding encoding = Encoding.GetEncoding("gb2312");
        //服务端
        private static Socket ss = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        private static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //客户端A
        private static Socket scA = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //客户端B
        private static Socket scB = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        还没有确定客户端的连接集合
        //private static List<Socket> list = new List<Socket>();
        //确定的连接集合
        private static Dictionary<string, Socket> tcpDic = new Dictionary<string, Socket>();


        public static void Main(string[] args)
        {

            StartServer();
            Console.ReadLine();
        }


        /// <summary>
        /// 服务端
        /// </summary>
        public static void StartServer()
        {
            //string str = null;
            //Socket ss = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            //本机上还有一个回环地址:127.0.0.1
            // IPAddress.Any:代表0.0.0.0 IP,可以使用本机所有IP(192.168.22.1、192.168.218.22、127.0.0.1就都可以连接上本服务端)
            IPAddress ip = IPAddress.Any;
            IPEndPoint IpPoint = new IPEndPoint(ip, 8080);
            //把IP和端口绑定到Socket里面
            ss.Bind(IpPoint);
            //侦听
            ss.Listen(100);
            Console.WriteLine("服务端开启成功");
            Task.Run(() => // 服务端循环给客户端发送数据
            {
                try
                {
                    while (true)
                    {
                        //循环接收连接的客户端
                        socket = ss.Accept();

                        //list.Add(socket);
                        Task.Run(() =>
                        {
                            //用来判断身份有没有被确定
                            bool isIdCard = false;
                            //本身的唯一号
                            string idCard = string.Empty;
                            while (true)
                            {
                                //接收客户端发送的数据
                                byte[] bytes = new byte[1024];
                                int length = socket.Receive(bytes);
                                if (length == 0)
                                {
                                    //关闭客户端时,还需要从集合中删除这个客户端连接
                                    if (tcpDic.ContainsKey(idCard))
                                    {
                                        tcpDic.Remove(idCard);
                                    }
                                    socket.Close();
                                    return;
                                }
                                string msg = encoding.GetString(bytes, 0, length);
                                if (isIdCard) //身份已经确定
                                {
                                    //解析消息格式
                                    int index = msg.IndexOf("?");
                                    if (index < 0)
                                    {
                                        continue;
                                    }
                                    //客户端身份
                                    string onlyCode = msg.Substring(0, index);
                                    //客户端消息
                                    string strMsg = msg.Substring(index + 1);
                                    //找到接收方的Socket连接
                                    if (tcpDic.ContainsKey(onlyCode))
                                    {
                                        Socket socketReceive = tcpDic[onlyCode];
                                        socketReceive.Send(encoding.GetBytes(idCard + "?" + strMsg));
                                    }
                                }
                                else  //身份未确定
                                {
                                    isIdCard = true;
                                    idCard = msg;
                                    //把已经确定身份的客户端添加到确定身份的键值对集合中
                                    tcpDic[msg] = socket;
                                }
                                Console.WriteLine("服务端接收到的客户端的消息:" + msg);
                            }
                        });
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            });
        }
    }
}
//=================================客户端================================
{
    internal class Program
    {
        private static Encoding encoding = Encoding.GetEncoding("gb2312");
        public static void Main(string[] args)
        {
            StartCilent();
        }
        public static void StartCilent()
        {
            Socket sc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ip = new IPEndPoint(IPAddress.Parse("192.168.22.1"), 9500);
            //连接服务端
            sc.Connect(ip);
            Console.WriteLine("请输入自己的代号:");
            string cmd = Console.ReadLine();
            //发送自己的代号
            sc.Send(encoding.GetBytes(cmd));
            //循环接收数据
            Task.Run(() =>
            {
                while (true)
                {
                    byte[] buffer = new byte[1024];
                    int length = sc.Receive(buffer);
                    string msg = encoding.GetString(buffer, 0, length);
                    int index = msg.IndexOf("?");
                    if (index > 0)
                    {
                        string name = msg.Substring(0, index);
                        string str = msg.Substring(index + 1);
                        Console.WriteLine($"{name}发送消息过来了,消息内容是:{str}");
                    }
                    else
                    {
                        //如果没有解析出来,直接显示
                        Console.WriteLine($"收到消息:{msg}");
                    }
                }
            });
            //循环发送消息
            while (true)
            {
                string msg = Console.ReadLine();
                if (!string.IsNullOrEmpty(msg))
                {
                    sc.Send(encoding.GetBytes(msg));
                }
            }

        }
    }
}

3、服务端接收客户端发送的文件,并保存

namespace TcpFile
{
    internal class Program
    {
        static void Main(string[] args)
        {
            StartServer();
            StartClient();

            Console.ReadLine();
        }


        private static Socket socketServer;
        private static Socket socketClient;
        private static Encoding encoding = Encoding.GetEncoding("gb2312");

        /// <summary>
        /// 接收客户端发送过来的文件
        /// </summary>
        private static void StartServer() 
        {
            socketServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            socketServer.Bind(new IPEndPoint(IPAddress.Any, 8080));
            socketServer.Listen(100);
            Console.WriteLine("服务端启动成功");
            ServerAccept();
        }
        //获取服务端与客户端的连接
        private static void ServerAccept() 
        {
            Task.Run(() =>
            {
                while (true)
                {
                    //1.等待客户端连接
                    Socket socketC = socketServer.Accept();
                    Console.WriteLine("一个客户端上线了");
                    //2.接收客户端消息
                    byte[] buffer = new byte[1024];
                    int length = socketC.Receive(buffer);
                    //文件信息的消息
                    string str = encoding.GetString(buffer,0,length);
                    string[] strs = str.Split('-');
                    long fileSize = Convert.ToInt64(strs[0]);
                    string fileName = strs[1];
                    //3.给客户端回复:Ok
                    FileStream stream = File.Create($@"D:\C盘移动的\Desktop\上位机\Day\阮老师讲的\10-TCP协议\TcpFile\bin\Debug\Tcp\\{fileName}");
                    socketC.Send(encoding.GetBytes("OK"));
                    //4.循环接收客户端发送的文件(当文件内容大小与fileSize一致时,就认为文件读取结束了)
                    long nowSize = 0;//当前读取的文件长度的大小
                    Console.WriteLine("正在接收文件,请稍后...");
                    //循环接收
                    while (true) 
                    {
                        buffer = new byte[1024*10];
                        length = socketC.Receive(buffer);
                        stream.Write(buffer, 0, length);
                        nowSize += length;
                        if (nowSize == fileSize) 
                        {
                            break; 
                        }
                    }
                    socketC.Close();
                    stream.Close();
                    Console.WriteLine("文件接收完毕");
                }
            });
        }

        /// <summary>
        /// 启动客户端
        /// </summary>
        private static void StartClient() 
        {
            socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //1.连接服务端
            socketClient.Connect(new IPEndPoint(IPAddress.Parse("192.168.22.1"), 8080));
            string fullName = "D:\\C盘移动的\\Desktop\\上位机\\Day\\阮老师讲的\\10-TCP协议\\TcpFile\\bin\\Debug\\Tcp.txt";
            string fileName = Path.GetFileName(fullName);
            FileStream fs = File.OpenRead(fullName);
            //2.发送文件名和文件大小(格式:大小-文件名)
            socketClient.Send(encoding.GetBytes($"{fs.Length}-{fileName}"));
            //3.接收服务端消息:"OK"
            byte[] buffer = new byte[100];
            int length = socketClient.Receive(buffer);
            string str = encoding.GetString(buffer,0,length);
            if (str != "OK") 
            {
                fs.Close();
                socketClient.Close();
                return;
            }
            Console.WriteLine("正在发送文件,请稍后...");
            //4.发送文件
            Task.Run(() => 
            {
                buffer = new byte[1024*10];
                while (true)
                {
                    //读取文件流
                    length = fs.Read(buffer, 0, buffer.Length);
                    //当读取长度为0时,就说明文件读取完毕
                    if (length == 0)
                    {
                        socketClient.Close();
                        fs.Close();
                        Console.WriteLine("发送结束");
                        break;
                    }
                    socketClient.Send(buffer, 0, length, SocketFlags.None);
                }
            });

        }
    }
}

4、服务端与客户端以16进制收发数据

namespace Tcp16
{
   /// <summary>
   /// 
   /// </summary>
   internal class Program
   {
       static void Main(string[] args)
       {
           StartServer();
           StartClient();
           Console.ReadLine();
       }

       /// <summary>
       /// 服务端
       /// </summary>
       private static void StartServer() 
       {
           Socket ss = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
           ss.Bind(new IPEndPoint(IPAddress.Any,8080));
           ss.Listen(100);
           Console.WriteLine("服务端启动成功");
           
           Task.Run(() =>
           {
               Socket sClient = ss.Accept();
               Console.WriteLine("客户端连接");
               //接收客户端消息
               while (true)
               {
                   byte[] buffer = new byte[1024];
                   int length = sClient.Receive(buffer);
                   byte[] date = new byte[length];
                   string str = string.Empty;
                   for (int i = 0;i<length;i++) 
                   {
                       str += $"{buffer[i].ToString("X2")}";
                       date[i] = (byte)(buffer[i] + 1);
                   }
                   Console.WriteLine("服务端接收的消息:"+str);
                   sClient.Send(date);
               }
           });
       }

       /// <summary>
       /// 客户端
       /// </summary>
       private static void StartClient() 
       {
           Socket sc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
           sc.Connect(new IPEndPoint(IPAddress.Parse("192.168.22.1"), 8080));
           Task.Run(() =>
           {
               while (true) 
               {
                   sc.Send(new byte[] {0xAA,0xBB,0xCC });
                   byte[] bytes = new byte[1024];
                   int length = sc.Receive(bytes);
                   string str = string.Empty;
                   for (int i =0;i<length;i++) 
                   {
                       str += $"{bytes[i].ToString("X2")}";
                   }
                   Console.WriteLine("收到服务端发送的数据:"+str);
                   Task.Delay(1000).Wait();
               }
           });

       }
   }
}
//======================案例练习:发送16进制判断接收湿度还是温度=====================
namespace Tcp16
{
    /// <summary>
    /// 根据客户端发送过来的数据,判断服务端是给客户端发送温度还是湿度
    /// </summary>
    internal class WD_SD
    {
        static Random random = new Random();
        static void Main(string[] args)
        {
            Console.WriteLine("44444");
            StartServer();
            StartClient();
            Console.ReadLine();
        }

        /// <summary>
        /// 服务端 
        /// </summary>
        private static void StartServer()
        {
            Socket ss = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ss.Bind(new IPEndPoint(IPAddress.Any, 8080));
            ss.Listen(100);
            Console.WriteLine("服务端启动成功");
            
            Task.Run(() =>
            {
                Socket sClient = ss.Accept();
                Console.WriteLine("客户端上线");
                //接收客户端消息
                while (true)
                {
                    byte[] buffer = new byte[1024];
                    int length = sClient.Receive(buffer);
                    if (length == 1) 
                    {

                        byte date = buffer[0];
                        if (date == 0x0A)
                        {
                            //随机生成一个温度
                            byte tem = (byte)random.Next(0, 50);
                            sClient.Send(new byte[] {tem});
                        }
                        else if(date == 0x0B) //湿度
                        {

                            //随机生成一个温度
                            byte hum = (byte)random.Next(20, 60);
                            sClient.Send(new byte[] { hum });
                        }
                    }
                }
            });
        }

        /// <summary>
        /// 客户端
        /// </summary>
        private static void StartClient()
        {
            Socket sc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            sc.Connect(new IPEndPoint(IPAddress.Parse("192.168.22.1"), 8080));
            Task.Run(() =>
            {
                while (true)
                {
                    //byte[] bytes = new byte[1024];
                    int num = random.Next(0,100);
                    byte cmd = (byte) (num%2 == 0 ? 0x0A : 0x0B);
                    sc.Send(new byte[] { cmd});

                    //接收
                    byte[] buffer = new byte[1024];
                    int length = sc.Receive(buffer);
                    if (length == 1)
                    {
                        byte date = buffer[0];
                        if (cmd == 0x0A)
                        {
                            Console.WriteLine("温度0A:"+date);
                        }
                        else if (cmd == 0x0B) //湿度
                        {
                            Console.WriteLine("湿度0B:" + date);
                        }
                    }
                    Task.Delay(1000).Wait();
                }
            });
        }
    }
}

四、UDP (用户数据报协议)

  • 面向无连接,可靠的
  • 延时小,传输效率高
  • 无序,容易丢包
  • 一对一、一堆多、多对多数据发送方式

1、单播:代码案例:

static void Main(string[] args)
{
   UdpRevice();
   UdpSend();
           
   Console.ReadKey();
}

private static Encoding encoding  = Encoding.GetEncoding("gb2312");


// 单播---接收
static void UdpRevice() 
{
   Socket udp = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
   IPEndPoint ipP = new IPEndPoint(IPAddress.Any,8080);
   udp.Bind(ipP);
   Task.Run(() =>
   {
      byte[] bytes = new byte[1024];
      while (true) 
      {
          EndPoint endP = new IPEndPoint(0,0);
          int length = udp.ReceiveFrom(bytes,ref endP);
          if (length <= 0)
          {
               udp.Close();
               return;
          }
          string str = encoding.GetString(bytes,0, length);
          Console.WriteLine($"接收到{endP}发送过来的数据:"+ str);
      }
   });
}

//单播---发送
static void UdpSend() 
{
   Socket udp = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
   Task.Run(() =>
   {
      //接收方IP和端口
      EndPoint endP = new IPEndPoint(IPAddress.Parse("192.168.22.1"),8080);
      //循环发送
      while (true)
      {
          byte[] bytes = encoding.GetBytes("发送方发送的数据");
          udp.SendTo(bytes, endP);
          Task.Delay(1000).Wait();
      }
   });
}

2、组播:代码案例

/// <summary>
/// 组播接收数据
/// </summary>
static void MulRevice() 
{
    UdpClient udp = new UdpClient(8080);
    IPAddress ipAddress = IPAddress.Parse("235.0.0.1");
    //添加进组
    udp.JoinMulticastGroup(ipAddress);
    Task.Run(() => 
    {
        //发送方的IP和端口
        IPEndPoint endP = new IPEndPoint(0, 0);
        //循环接收数据
        while (true) 
        {
            byte[] buffer = udp.Receive(ref endP);
            string str = encoding.GetString(buffer);
            Console.WriteLine($"组播:接收到的数据:{str}。发送方的IP和端口:{endP}");

            //回消息,发送数据
            byte[] bytes = encoding.GetBytes("接收消息后回消息");
            udp.Send(bytes,bytes.Length,endP);
        }
    });
}
/// <summary>
/// 组播发送数据
/// </summary>
static void MulSend() 
{
    IPAddress ipAddress =IPAddress.Parse("235.0.0.1");
    UdpClient udpTo = new UdpClient(8088);//绑定本地的一个端口号
    udpTo.JoinMulticastGroup(ipAddress);
    Task.Run(() =>
    {
        //要给哪个组播发数据,获取组播的IP和端口
        IPEndPoint endP = new IPEndPoint(ipAddress,8080);
        while (true) 
        {
            byte[] bytes = encoding.GetBytes("给组播发的数据2222");
            udpTo.Send(bytes,bytes.Length,endP);
            byte[] bytes1 = udpTo.Receive(ref endP);
            string str = encoding.GetString(bytes1);
            Console.WriteLine($"发送之后,在接收一条接收方回应的消息:{str}。接收方的IP和端口是:========={endP}");
            Task.Delay(1000).Wait();
        }
    });
}

3、广播:代码案例

#region 广播
private static void BroadcastReceive() 
{
    //自己的端口,别人发送数据时发送到这个端口
    UdpClient udpClient = new UdpClient(8080);
    Task.Run(() => {

        IPEndPoint endP = new IPEndPoint(0,0);
        //循环接收数据
        while (true)
        {
            //接收数据
            byte[] buffer = udpClient.Receive(ref endP);
            string str = encoding.GetString(buffer);
            //输出
            Console.WriteLine($"接收到的广播数据{str},发送数据的广播的IP和端口{endP}")
        }
    });
}

private static void BroadcastSend()
{
    //发送时,不写端口,就会随机一个端口发送
    UdpClient udp = new UdpClient();
    Task.Run(() =>
    {
        //循环发送广播数据
        while (true)
        {
            //广播IP:255.255.255.255
            IPEndPoint endP = new IPEndPoint(IPAddress.Parse("255.255.255.255"),8080);
            //循环发送
            int num = 1;
            while (true) 
            {
                byte[] bytes = encoding.GetBytes("我是广播"+num);
                num++;
                udp.Send(bytes,bytes.Length,endP);
                Task.Delay(1000).Wait();
            }
        }
    });
}

五、TCP与UDP的区别

它们的区别主要有以下四点:

1、TCP 是面向连接的(三次握手建立连接),UDP 是无连接的即发送数据前不需要先建立链接。

2、TCP 提供可靠的服务。也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,不保证可靠交付。 (并且因为 TCP 可靠,面向连接,不会丢失数据因此适合大数据量的交换)

3、TCP 是面向字节流,UDP 面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如 IP 电话和视频会议等)。

4、TCP 只能是 1 对 1 的,UDP 支持 1 对 1,1 对多。

5、TCP 的首部较大为 20 字节,而 UDP 只有 8 字节。

6、TCP 是面向连接的可靠性传输,而 UDP 是不可靠的

图表对比:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值