Java小白入门 —— 网络编程之Socket
一. 什么是网络模型?
网络模型是一个设备发送数据给另一个设备,然后接收另一个设备的反馈,目前最主要的网络编程都是基于请求/响应方式的。
在网络编程中,发起请求的一方称作为客户端(Client),等待其他程序连接的一方成为服务端(Server)。客户端程序可以在需要时启动,而服务端程序需要一直保持响应状态。
在有些程序中,既可以作为客户端,也可以作为服务端。
二. IP及域名:
IP地址:
IP地址是用来唯一标识互联网上计算机的逻辑地址,让电脑之间可以相互通信,每台连网计算机都依靠IP地址来互相区分,相互联系。
域名:
只是为了人们记的方便,给出的一个名字。域名的ip地址绑定了以后,当别人访问这个域名的时候就可以通过dns解析成ip,再进行访问。
三. 端口
为了在一台设备上可以运行多个程序,人为的设计了端口(Port)的概念,类似的例子是公司内部的分机号码。
规定一个设备有216个,也就是65536个端口,每个端口对应一个唯一的程序。每个网络程序,无论是客户端还是服务器端,都对应一个或多个特定的端口号。由于0-1024之间多被操作系统占用,所以实际编程时一般采用1024以后的端口号。
使用端口号,可以找到一台设备上唯一的一个程序。
所以如果需要和某台计算机建立连接的话,只需要知道IP地址或域名即可,但是如果想和该台计算机上的某个程序交换数据的话,还必须知道该程序使用的端口号。
四. 网络模型图
五. Socket 入门
1. 什么是 Socket ?
socket 是用于在两个基于 TCP/IP 协议的应用程序之间相互通信;
建立网络通信连接至少要一对端口号(socket);
数据在两个Sokcet间通过IO传输。
2. TCP 和 UDP 的区别?
TCP | UDP |
---|---|
面向连接 | 无连接 |
对于系统资源要求较多 | 对于系统资源要求较少 |
程序结构复杂 | 程序结构简单 |
可靠传输 | 不可靠传输 |
速度慢 | 速度快 |
流模式 | 数据报模式 |
保证数据顺序和正确性 | 无法保证 |
应用于少量数据传输及准确性要求较高场景 | 应用于大量数据传输及无需较高准确性场景 |
3.TCP连接:
服务端:
/**
* @author MuXin
* @date 2020/10/28 11:48
*/
public class TcpServer {
public static void main(String[] args) {
try {
System.out.println("socket服务器端启动...");
ServerSocket serverSocket = new ServerSocket(8080);
//获取客户端对象
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
byte[] buf = new byte[1024];
int read = inputStream.read(buf);
String str = new String(buf, 0, read);
System.out.println("客户端:" + str);
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端:
/**
* @author MuXin
* @date 2020/10/28 11:45
*/
public class TcpClient {
public static void main(String[] args) {
try {
System.out.println("Socket启动...");
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("我是客户端".getBytes());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果:
在 TCP/IP 协议中,TCP 协议采用的三次握手建立一个连接;
第一次握手:建立连接时,客户端发送SYN包(SYN=J)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到SYN包,必须确认客户的SYN(ACK=J+1),同时自己也发送一个SYN包(SYN=K),即SYN+ACK包,此时服务器V状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=K+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。
4. UDP 连接:
服务端:
/**
* @author MuXin
* @date 2020/10/28 11:58
*/
public class UdpServer {
public static void main(String[] args) {
try {
System.out.println("UDP 启动...");
DatagramSocket ds = new DatagramSocket(8080);
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
//阻塞效果
ds.receive(dp);
System.out.println("来源:"+dp.getAddress().getHostAddress()+",port:"+dp.getPort());
String str = new String(dp.getData(), 0, dp.getLength());
System.out.println("客户端:"+str);
ds.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端:
/**
* @author MuXin
* @date 2020/10/28 11:58
*/
public class UdpClient {
public static void main(String[] args) {
try {
System.out.println("UDP连接发送数据");
DatagramSocket ds = new DatagramSocket();
String str = "发送数据...";
byte[] bytes = str.getBytes();
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("127.0.0.1"),8080);
ds.send(dp);
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果: