一、TCP
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象(点对点)。
通信之前要保证连接已经建立(注意TCP是一定要建立连接的)
TCP是通过Socket产生I0流来进行网络通信的,所以发送端和接收端的两个流的方向是不一样的,比如客户端和服务器进行通信(通信前要确保建立了连接),然后客户端向服务器发送了“你好”,这一次发送数据的过程,它们流的方向是不一样的,针对客户端来说,它是往外发所以用的是输出流,而针对服务器来说,它是接收数据所以用的是输入流。
1.1 TCP的特点
TCP是一种面向连接的、可靠的传输层协议,用于在网络中传输数据。
- TCP通过序号、确认和重传机制确保数据的可靠传输,提供数据完整性和顺序性。
- TCP使用三次握手建立连接,在连接释放时使用四次挥手。
- TCP适用于对数据可靠性要求高的应用场景,如文件传输、网页访问等
1.2 ServerSocket
和 Socket的区别
ServerSocket
和 Socket
虽然都与网络编程中的端口相关,但在功能和使用场景上有明显的区别:
ServerSocket:
- 主要用于服务器端。
- 负责监听特定端口上的连接请求。
- 其重点在于创建一个等待客户端连接的端点,并在有连接请求时接受连接,返回一个用于与客户端通信的
Socket
对象。- 例如,一个 Web 服务器使用
ServerSocket
在 8080端口监听来自浏览器的请求。Socket:
- 客户端的通信套接字(端口),不是网络协议
- 既可以用于客户端,也可以用于服务器端与已连接的对端进行通信。
- 代表了客户端与服务器端之间建立的连接通道。
- 一旦
ServerSocket
接受了连接请求,就会创建一个Socket
用于双方的数据传输。- 比如,在客户端创建一个
Socket
连接到服务器端指定端口进行数据的发送和接收。简单来说,
ServerSocket
像是一个“守门员”,负责在端口上等待并筛选连接请求;而Socket
则是建立连接后的“通信管道”,用于实际的数据交换。
1.3 代码展示 ---图片传输
1.3.1 服务器端代码
package com.http.demo01;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
//图片服务器端
public class ImageServer {
public static void main(String[] args) {
//创建服务器端Socket对象,监听8848端口
try (ServerSocket serverSocket = new ServerSocket(8848)){
//使服务器进入阻塞状态,等待客户端的连接请求
Socket clientSocket = serverSocket.accept();
//获取客户端网络地址
InetAddress clientNetAddress = clientSocket.getInetAddress();
System.out.printf("客户端%s正在连接图片服务器,即将上传图片....\n",
clientNetAddress.getHostAddress());
//上传图片名称
String imageName = clientNetAddress.getHostAddress().replace('.','-').concat(".jpg");
try (InputStream in = clientSocket.getInputStream();
BufferedInputStream bis = new BufferedInputStream(in);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\develop\\数据\\images"));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()))) {
//读取客户端上传的图片(字节输入流)
byte[] buff = new byte[1024];
int len = -1;
while((len = bis.read(buff))!=-1) {
bos.write(buff,0,len);
}
System.out.printf("[%s]图片上传完毕!\n",clientNetAddress.getHostAddress());
//给客户端反馈信息(字符输出流)
writer.write("upload success!!!\r\t");
writer.newLine();
writer.write("-------------------->");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.3.2 客户端代码
package com.http.demo01;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
//图片客户端
public class ImageClient {
public static void main(String[] args) {
//创建客户端Socket对象,连接指定的IP和端口
try (Socket clientSocket = new Socket("192.168.xxx.xxx",8848);
BufferedOutputStream bos = new BufferedOutputStream(
clientSocket.getOutputStream());
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("C:\\Users\\Saved Pictures\\aaa.jpg"));
BufferedReader Reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
//向服务器端发送图片(输出至服务器端)
byte[] buff = new byte[1024];
int len = -1;
while((len = bis.read(buff)) != -1) {
bos.write(buff,0,len);//?
}
bos.flush();
//暂时关闭输出流
clientSocket.shutdownOutput();
//接受服务器端返回的"答案"
String ans = null;Reader.readLine();
while((ans = Reader.readLine())!=null) {//?
System.out.println("来自服务器端的回答:"+ ans);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、UDP
UDP是工作在OSI(开放系统互连,Open Systems Interconnection)模型中传输层的协议(用户数据报协议---User Datagram Protocol)。它使用IP作为底层协议,是为应用程序提供一种以最少的协议机制向其他程序发送消息的协议。
2.1 UDP特点
- UDP是一种无连接的传输层协议,提供简单的数据传输服务。
- UDP不保证数据的可靠传输,不提供数据完整性和顺序性。
- UDP适用于对实时性要求高、数据丢失可接受的应用场景,如音频、视频流传输等。
- UDP使用较少的开销,传输效率高,但可靠性比TCP较低。
2.2 DatagramPacket 与 DatagramSocket
DatagramSocket 类用于表示发送和接收数据报包的套接字。数据报包套接字是包投递服务的发送或接收点。每个在数据报包套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
java.net 包中的 DatagramPacket 类用来表示数据报包,数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
2.3 代码展示---对暗号
2.3.1 服务器端代码
package com.udp.demo02;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//UDP:发传单
public class UdpServer {
public static void main(String[] args) {
//创建socket,监听6666端口
try (DatagramSocket serverSocket = new DatagramSocket(6666)) {
System.out.println("有客户端正在连接...");
//读取来自客户端的"数据包"
//创建数据包
byte[] buff = new byte[1024];//以一个字节数组保存数据
DatagramPacket packet = new DatagramPacket(buff, buff.length);
//接收数据包
serverSocket.receive(packet);
System.out.println("读取完毕!");
//读取数据包中的内容
byte[] data = packet.getData();
String strFromClient = new String(data).trim();//将信息转换成字符串并将首尾空白字符删除
System.out.println("来自客户端的信息:"+strFromClient);
//匹配内容并反馈
if("天王盖地虎".equals(strFromClient)) {
packet.setData("宝塔镇河妖".getBytes());//接收用的字节
}else {
packet.setData("不知道你在说什么?".getBytes());
}
//将反馈发送回客户端
serverSocket.send(packet);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.3.2 客户端代码
package com.udp.demo02;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class UdpClient {
public static void main(String[] args) {
//创建socket
try (DatagramSocket clientSocket = new DatagramSocket()) {
//连接指定主机的端口
clientSocket.connect(InetAddress.getByName("192.168.xxx.xxx"), 6666);
//创建数据包
byte[] buff = new byte[1024];//以一个字节数组保存数据
DatagramPacket packet = new DatagramPacket(buff, buff.length);
packet.setData("天王盖地虎".getBytes());//将字符转换成字节,数据放入数据包
//发送数据包
clientSocket.send(packet);
//接收来自服务器端的数据包(等待接收反馈信息)
clientSocket.receive(packet);
byte[] data = packet.getData();
String strFromServer = new String(data);
System.out.println("来自服务器端的信息是:"+ strFromServer);
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、TCP与UDP区别
TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)是两种常见的传输层协议,它们之间有以下主要区别:
- 连接状态:
TCP是面向连接的协议,通信双方在数据传输前需要建立连接,数据传输完成后再释放连接。
UDP是无连接的协议,通信双方直接发送数据包,不需要建立连接,也不保持连接状态。
- 可靠性:
TCP提供可靠的数据传输,通过序号、确认和重传机制确保数据的完整性和顺序性。
UDP不提供可靠性保证,发送的数据包可能会丢失或乱序,不会进行重传操作。
- 数据量:
TCP适用于大数据量的传输,能够保证数据的完整性和顺序性。
UDP适用于实时性要求高、数据量较小的应用场景,如音频、视频流传输等。
- 延迟:
TCP因为提供了可靠性保证和流量控制,可能会引入一定的延迟。
UDP由于不需要建立连接和处理复杂的机制,通常具有更低的延迟。
- 应用场景:
TCP适用于对数据可靠性要求高的应用,如文件传输、网页访问、电子邮件等。
UDP适用于对实时性要求高、能够容忍一定数据丢失的应用,如语音通话、视频直播、在线游戏等。
- 头部开销:
TCP的头部较大,包含序号、确认、窗口大小等字段,增加了数据包的开销。
UDP的头部相对较小,只包含基本的源端口、目的端口、长度和校验和字段。
总的来说,TCP提供了可靠的数据传输和流量控制,适用于对数据完整性和顺序性要求高的场景;而UDP则更适合对实时性要求高、能够容忍一定数据丢失的场景。