TCP与UDP

  • TCP

1.传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据流量控制等功能,保证数据能从一端传到另一端。

tcp连接就像打电话,两者之间必须有一条不间断的通路,数据不到达对方,对方就一直在等待,除非对方直接挂电话。先说的话先到,后说的话后到,有顺序。

  • UDP

2.用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

udp就象寄一封信,发信者只管发,不管到。但是你的信封上必须写明对方的地址。发信者和收信者之间没有通路,靠邮电局联系。信发到时可能已经过了很久,也可能根本没有发到。先发的信未必先到,后发的也未必后到。

  • TUP与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则是不可靠信道

说到TCP和UDP,首先要明白“连接”和“无连接”的含义,他们的关系可以用一个形象地比喻来说明,就是打电话和写信。

两个人如果要通话,首先要建立连接——即打电话时的拨号,等待响应后——即接听电话后,才能相互传递信息,最后还要断开连接——即挂电话。

写信就比较简单了,填写好收信人的地址后将信投入邮筒,收信人就可以收到了。

从这个分析可以看出,建立连接可以在需要痛心地双方建立一个传递信息的通道,在发送方发送请求连接信息接收方响应后,由于是在接受方响应后才开始传递信息,而且是在一个通道中传送,因此接受方能比较完整地收到发送方发出的信息,即信息传递的可靠性比较高。但也正因为需要建立连接,使资源开销加大(在建立连接前必须等待接受方响应,传输信息过程中必须确认信息是否传到及断开连接时发出相应的信号等),独占一个通道,在断开连接钱不能建立另一个连接,即两人在通话过程中第三方不能打入电话。而无连接是一开始就发送信息(严格说来,这是没有开始、结束的),只是一次性的传递,是先不需要接受方的响应,因而在一定程度上也无法保证信息传递的可靠性了,就像写信一样,我们只是将信寄出去,却不能保证收信人一定可以收到。

TCP/IP

传输控制协议/因特网互联协议,也叫网络通信协议,是internet最基本的协议,简单地说就是网络层的IP协议与传输层的TCP协议。

IP:网络中每台计算机的标识号,本地IP为127.0.0.1 localhost

端口号:范围0-65535之间,0-1023之间的端口数用于一些知名的网络服务与应用,依我之 见,端口就是一个虚拟的门可以访问到指定的服务与应用

IP+端口号就是套接字

网络编程中的TCP协议

  • 服务端与客户端进行通信

Soket:网络驱动层提供给应用程序编程的接口和一种机制

端口号拼接到IP地址即构成套接字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
*服务端
*/
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServerDemo {
public static void main(String[] args) {
try {
//服务器地址
ServerSocket server = new ServerSocket(6666);
System.out.println("服务器已启动,等待连接---");
//等待客户端连接
Socket socket = server.accept();
System.out.println("客户端连接成
功"+server.getInetAddress().getHostAddress());
//读取客户端消息
BufferedReader br=new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String info =br.readLine();
System.out.println(info);
//给客户端发送消息
PrintStream ps = new PrintStream(new
BufferedOutputStream(socket.getOutputStream()));
ps.println("echo:"+info);
ps.flush();
ps.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
*客户端
*/
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Locale;
public class EchoClientDemo {
public static void main(String[] args){
try {
//创建一个Socket连接
Socket socket = new Socket(InetAddress.getLocalHost(),6666);
//发送消息IO流
PrintStream ps =new PrintStream(
new BufferedOutputStream(socket.getOutputStream()));
BufferedReader br=new BufferedReader(
new InputStreamReader(socket.getInputStream()));
ps.println("我是你威哥" );
//接收服务器输出的消息
String info=br.readLine();
System.out.println(info);
ps.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
  • 服务器同时处理多个客户端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    public class ServerDemo {
    public static void main(String[] args){
    ExecutorService es = Executors.newFixedThreadPool(3);
    try {
    ServerSocket server =new ServerSocket(6666);
    System.out.println("服务器等待连接---");
    while(true){
    Socket s=server.accept();
    System.out.println(s.getInetAddress().getHostAddress());
    es.execute(new UserThread(s));
    }
    } catch (IOException e) {
    e.printStackTrace();
    }

    }
    }
    class UserThread implements Runnable{
    private Socket s;
    public UserThread(Socket s){
    this.s=s;
    }
    public void run() {
    try {
    BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    PrintStream ps =new PrintStream(new BufferedOutputStream(s.getOutputStream()));
    String info=br.readLine();
    System.out.println(info);
    ps.println("echo:"+info);
    ps.flush();
    ps.close();
    br.close();
    } catch (IOException e) {
    e.printStackTrace();
    }


    }
    }

    初识Tomcat

    服务端

    • 自定义(s)
    • Tomcat服务器(s):java后台开发

    客户端

    • 自定义(c)
    • 浏览器(s)

    它有webapps文件,可以像宝塔面板一样创建自己的网站

网络编程UDP协议

image-20240326203013224

  • 服务端

1.将信息封装为数据报,并指定目标端口

1
2
3
4
String info="---"
byte[] bytes=info.getBytes();
DatagramPacket dp=new DatagramPacket(bytes,0,bytes.length,
InetAddress.getByName("127.0.0.1"),6000);

2.创建套接字对象,并指定服务器端口

1
DatagramSocket socket=new DatagramSocket(6001);

3.发送数据报,并关闭套接字对象

1
2
socket.send(dp);
socket.close();
  • 客户端

1.建立一个Socket,开发端口

1
DatagramSocket socket=new DatagramSocket(6000);

2.接收内容

1
2
byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,0,bytes.length);

3.阻塞接收,并关闭流

1
2
3
4
socket.receive(dp);//阻塞接受数据
String info=new String(dp.getData(),0,dp.getLength);
System.out.println(info);
socket.close();//关闭流

接受端


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.io.IOException;
import java.net.*;

public class UDPServerDemo {
public static void main(String[] args) throws RuntimeException {
try {
String info="good good study,day day up";
byte[] bytes=info.getBytes();
DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length,
InetAddress.getByName("127.0.0.1"),5000);
DatagramSocket socket = new DatagramSocket(6001);
socket.send(dp);
socket.close();
} catch (SocketException e) {
throw new RuntimeException(e);
}catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

发送端


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPClientDemo {
public static void main(String[] args){
byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
try{
DatagramSocket ds=new DatagramSocket(5000);
System.out.println("正在连接---");
ds.receive(dp);
System.out.println("连接成功");
String info=new String(dp.getData(),0, dp.getLength());
System.out.println(info);
ds.close();
} catch (IOException e) {
throw new RuntimeException(e);
}

}
}