按区域分为:
Internet国际互联网就是最常用的广域网
按层次分为:
从下到上分为:
1) 物理层,底层硬件
2) 数据链路层,通信的介质
3) 网络层,寻址和路由, IP协议
4) 传输层,连接和数据通信,TCP协议\UDP协议
5) 会话层,管理会话
6) 表示层,处理数据格式、加密
7) 应用层,程序之间的通信,http协议\ftp协议\smtp协议\pop3协议
IP协议
Internet Protocol 网际协议
用于在网络中定义计算机的位置
分为:
ipv4 由四个数字(0~255)组成,如: 192.168.223.223
本质是32位二进制数 10101000 11110101 10110011 11100111
ipv6
端口
计算机上每个程序的数据通信的入口
不同的应用程序可以通过端口区分:3306、6379、8080、22122…
1~65535之间
Transfer Control Protocol 传输控制协议
主要控制点对点之间数据的通信
三大特点:
TCP可靠性基于三次握手
点对点通信前通过三次握手建立连接
1) 客户端向服务端发送报文,标志位SYN(同步请求),seq(序列号)给服务器,客户端进入SYN_SENT(请求发送)状态
2) 服务端接收了客户端的报文,进入SYN_RCVD(同步接收)状态,然后发送报文SYN(同步),ACK(应答),ack(应答序列号),seq(序列号)给客户端
3) 客户端收到服务端的报文进入Established(连接建立),发送应答报文ACK,ack给服务端,服务端进入Established状态,双方建立连接
点对点断开连接需要进行四次挥手
1) 客户端向服务端发送结束报文FIN,进入等待状态1
2) 服务端收到结束报文后,进入等待关闭状态,发送应答报文ack
3) 客户端接收服务端的应答报文ack,进入等待状态2
4) 服务端释放资源后,发送结束FIN给客户端,进入LAST_ACK状态
5) 客户端收到服务端的结束报文,发送应答报文ACK给服务端,连接关闭
套接字,基于TCP/IP协议
ServerSocket 类 ,服务端Socket
创建方法:
new ServerSocket(端口号)
ServerSocket创建后会自动对这个端口号进行侦听
常用方法:
Socket accept() 接收客户端的连接,并返回客户端连接对象,会自动阻塞线程直到有客户端连接
void disconnect() 关闭连接
Socket类,客户端Socket
创建方法:
new Socket(服务端IP,服务端PORT)
创建Socket对象后,就向服务端发送连接请求
常用方法:
InetAddress getInetAddress() 获得地址
void setTimeout(long) 设置超时时间
OutputStream getOutputStream() 获得输出流
InputStream getInputStream() 获得输入流
注意:任意的IO流关闭后,socket自动关闭
/**
* 服务端
*/
public class MyServer {
public static final int PORT = 8888;
//启动服务器
public void start(){
System.out.println("服务器启动了");
//创建ServerSocket对象
try(ServerSocket serverSocket = new ServerSocket(PORT)){
while(true){
//获得客户端的连接
Socket socket = serverSocket.accept();
System.out.println("接收到客户端:" + socket.getInetAddress());
//读取客户端的信息
try(ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream())){
String str = ois.readUTF();
System.out.println(socket.getInetAddress()+"说:" + str);
//给客户端发送消息
oos.writeUTF("客户端你好,现在时间:" + new Date());
oos.flush();
}catch (IOException ex){
ex.printStackTrace();
}
}
}catch (IOException ex){
ex.printStackTrace();
}
}
public static void main(String[] args) {
new MyServer().start();
}
}
/**
* 客户端
*/
public class MyClient {
//连接服务端,并发送文字
public void connect(String ip,int port,String msg){
//创建Socket对象
try(Socket socket = new Socket(ip,port);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());){
//向服务端发文字
oos.writeUTF(msg);
oos.flush();
//接收服务端的消息
String s = ois.readUTF();
System.out.println("服务端说:" + s);
}catch (IOException ex){
ex.printStackTrace();
}
}
public static void main(String[] args) {
new MyClient().connect("192.168.110.30",8888,"服务器你好啊!");
}
}
客户端:
服务端:
/**
* 文件客户端
*/
public class FileClient {
//发送文件
public void sendFile(String ip,int port,String path){
File file = new File(path);
//创建文件输入流
try(FileInputStream in = new FileInputStream(path);
//创建socket
Socket socket = new Socket(ip,port);
//获得输入流
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream())
){
//发文件名
out.writeUTF(file.getName());
out.flush();
//发文件
int len = -1;
byte[] buff = new byte[1024];
//循环,一边读,一边写
while((len = in.read(buff)) != -1){
out.write(buff,0,len);
}
}catch (IOException ex){
ex.printStackTrace();
}
}
public static void main(String[] args) {
new FileClient().sendFile("127.0.0.1",9999,"D:\\install\\Git-2.8.3-64-bit.exe");
}
}
/**
* 文件服务端
*/
public class FileServer {
public static final String DIR = "D:\\files\\";
//启动服务
public void start(){
try(ServerSocket serverSocket = new ServerSocket(9999)){
while(true){
Socket accept = serverSocket.accept();
//网络输入流
try(ObjectInputStream in = new ObjectInputStream(accept.getInputStream())){
//接收文件名
String fileName = in.readUTF();
File file = new File(DIR + fileName);
//接收文件
//文件输出流
FileOutputStream out = new FileOutputStream(file);
int len = -1;
byte[] buff = new byte[1024];
//循环,一边读,一边写
while((len = in.read(buff)) != -1){
out.write(buff,0,len);
}
out.close();
System.out.println(accept.getInetAddress()+"上传完毕:"+ file.getName());
}
}
}catch (IOException ex){
ex.printStackTrace();
}
}
public static void main(String[] args) {
new FileServer().start();
}
}
UDP是数据报协议,类似于广播,不需要三次握手来创建连接,传输数据速度快但是不可靠
UDP | TCP | |
---|---|---|
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠传输 | 可靠传输 |
连接个数 | 支持一对一,一对多,多对多通信 | 只能是一对一通信 |
传输方式 | 面向报文 | 面向字节流 |
适用场景 | 适用于实时应用(IP电话、视频会议、直播等) | 适用于要求可靠传输的应用,例如文件传输 |
DatagramSocket 可以做UDP的客户端也可以做服务器端
创建方法:
服务器端
new DatagramSocket(端口号)
客户端
new DatagramSocket()
主要方法:
send(DatagramPacket) 发送数据包
receive(DatagramPacket) 接收数据包
DatagramPacket UDP数据包,用于接收和发送数据
创建方法:
用于接收数据的数据包
DatagramPacket(byte[] 数据字节 ,int 数据长度)
用于发送数据的数据包
DatagramPacket(byte[] 数据字节 ,int 数据长度,InetAddress 地址,int 端口)
常用方法:
byte[] getData() 获得数据
/**
* UDP服务端
*/
public class UdpServer {
public static final int PORT = 9999;
public void start(){
System.out.println("启动UDP服务端!");
//创建udp socket对象
try(DatagramSocket server = new DatagramSocket(PORT)){
//创建数据包
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data,
data.length);
//接收数据
server.receive(packet);
//输出
System.out.println(packet.getAddress()+"说:"+
new String(packet.getData(),
0,packet.getLength(),
"UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new UdpServer().start();
}
}
public class UdpClient {
public void sendMsg(String ip,int port,String msg){
//创建客户端socket
try(DatagramSocket client = new DatagramSocket()){
//创建数据包
byte[] bytes = msg.getBytes("UTF-8");
DatagramPacket packet = new DatagramPacket(
bytes,bytes.length,
InetAddress.getByName(ip),port);
//发送数据
client.send(packet);
System.out.println("发送完毕");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new UdpClient().sendMsg("192.168.110.21",9999,"你好!UDP");
}
}