一、TCP是什么?
TCP(TransmissionControl Protocol)传输控制协议。
是一种可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;电子邮件、文件传输程序。
1.1 特性
1.1.1.是面向连接的协议
也就是说,在收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来。接收双方独占一个通道。
1.1.2.面向字节流
TCP将应用程序看成是一连串的无结构的字节流。每个TCP套接口有一个发送缓冲区,如果字节流太长时,TCP会将其拆分进行发送。当字节流太短时,TCP会等待缓冲区中的字节流达到一定程度时再构成报文发送出去,TCP发给对方的数据,对方在收到数据时必须给矛确认,只有在收到对方的确认时,本方TCP才会把TCP发送缓冲区中的数据删除。
二、UDP是什么?
UDP(User DatagramProtocol)用户数据报协议。
不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
2.1 特性
2.1.1.无连接的服务
UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,双方没有专有的通信通道。当发送端想传送数据时就简单地把数据扔到网络上,并不能保证他们能到达目的地。接收端由于没有与发送端建立专用的通信通道,因此接收数据时并不能确定是有谁发来的数据。
2.2.2.面向报文
发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界。也就是说应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。
不同于TCP有缓存机制。TCP是将发送的数据都看成字节流,根据字节流在缓冲区存储的大小来决定是否发送,一次发送的信息不一定是整个报文。
使用UDP发送信息,应用程序必须选择合适大小的报文。若报文太长,则IP层需要分片,降低效率。若太短,会是IP太小。
三、TCP与UDP的对比
3.1、基本区别
1、TCP面向连接(如打电话要先拨号建立连接)。UDP是无连接的,即发送数据之前不需要建立连接。
2、对系统资源的要求(TCP较多,UDP少)。TCP需要建立专用的通信通道,还需要校验数据等,因此需求的系统资源较大。
3、TCP保证数据正确性,TCP丢包会自动重传,UDP可能丢包,丢包后不会自动重传。TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道。
4、TCP保证数据传输有序,UDP不保证。
消息在传输过程中可能会乱序,后发送的消息可能会先到达,TCP会对其进行重排序,UDP不会。
5、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流。UDP是面向报文的
6、UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
7、每一条TCP连接只能是点到点的。UDP支持一对一,一对多,多对一和多对多的交互通信。
8、TCP首部开销20字节。UDP的首部开销小,只有8个字节
3.2、编程中的区别
从程序实现的角度来看,可以用下图来进行描述。
四、使用步骤
1.TCP
Http使用端口是80
SMTP使用端口是25
TCP是首选协议,它提供有保证的传输、错误校正和缓冲。
System.Net.Sockets. TcpClient类封装了TCP链接,提供属性字段来控制链接,包括缓冲、缓冲区的大小和超时。
TCP提供很多功能来确保数据的传输,它还提供了错误校正以及当数据丢失或数据包损坏时重新传输的功能。TCP可缓冲传入和传出的数据,还保证在传输过程中,在把数据包传输给应用程序之前重组杂乱的一系列数据包。
代码如下(示例):
发送端
TcpClient tcpClient = new TcpClient(textBox1.Text, Int32.Parse(textBox2.Text));
NetworkStream ns = tcpClient.GetStream();
FileStream fs = File.Open("Send.txt", FileMode.Open);
int data = fs.ReadByte();
while (data != -1)
{
ns.WriteByte((byte)data);
data = fs.ReadByte();
}
fs.Close();
ns.Close();
tcpClient.Close();
接收端
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
Int32 port = 2112;
System.Net.Sockets.TcpListener tcpListener = new TcpListener(localAddr, port);
tcpListener.Start();
TcpClient tcpClient = tcpListener.AcceptTcpClient();
NetworkStream ns = tcpClient.GetStream();
StreamReader sr = new StreamReader(ns);
string result = sr.ReadToEnd();
Invoke(new UpdateDisplayDelegate(UpdateDisplay), new object[] { result });
tcpClient.Close();
tcpListener.Stop();
2.UDP
UDP, 通常在速度和性能要求比可靠性更高的应用程序中使用UDP,如视频流。
UDP是一个无连接的协议
客户端
//System.Net.Sockets.UdpClient udpClient = new UdpClient();
//string sendMsg = "Hello Echo Server";
//byte[] sendBytes = Encoding.ASCII.GetBytes(sendMsg);
//udpClient.Send(sendBytes, sendBytes.Length, "UdpTest.net", 7);
//IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 9093);
//byte[] rcvBytes = udpClient.Receive(ref endPoint);
//string rcvMessage = Encoding.ASCII.GetString(rcvBytes, 0, rcvBytes.Length);
//Console.WriteLine(rcvMessage);
byte[] data = new byte[1024];
string intput, stringData;
IPEndPoint iPEnd = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9095);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Hello,Where are you there";
data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, iPEnd);//将数据发送到指定的终结点
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)sender;
data = new byte[1024];
int recv = server.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message received from{0}", Remote.ToString());
while (true)
{
intput = Console.ReadLine();
if (intput == "text")
{
break;
}
server.SendTo(Encoding.ASCII.GetBytes(intput), Remote);//将数据发送到指定的终结点Remote
data = new byte[1024];
recv = server.ReceiveFrom(data, ref Remote);//从Remote接受数据
stringData = Encoding.ASCII.GetString(data, 0, data.Length);
Console.WriteLine(stringData);
}
Console.WriteLine("stop");
server.Close();
服务端
int recv;
byte[] data = new byte[1024];
IPEndPoint ipEp = new IPEndPoint(IPAddress.Any, 9095);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(ipEp);
Console.WriteLine("wait....");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 9095);
EndPoint Remote = (EndPoint)(sender);
recv = socket.ReceiveFrom(data, ref Remote);
Console.WriteLine("Message receive from {0}", Remote.ToString());
string welcome = "Welcome to my server";
data = Encoding.ASCII.GetBytes(welcome);
socket.SendTo(data, data.Length, SocketFlags.None, Remote);
while (true)
{
data = new byte[1024];
recv = socket.ReceiveFrom(data, ref Remote);
socket.SendTo(data, recv, SocketFlags.None, Remote);
}