Java之网络编程
网络模型
- OSI参考模型
将网络分成七层:应用层、表示层、会话层、传输层、网络层、数据链路层,物理层 - TCP/IP参考模型
将网络分成:应用层、传输层、网际层、主机至网络层
网络通讯要素
- IP地址 InetAddress
1.网络中设备的标识 2.不易记忆,可用主机名 3.本地回环地址:127.0.0.1 主机名:localhost - 端口号
1.用于标识进程的逻辑地址,不同进程的标识 2.有效端口:065535,其中01024系统使用或保留端口 - 传输协议
1.通讯的规则 2.常见的协议:TCP,UDP UDP a.将数据及源和目的封装成数据包中,不需要建立连接 b.每个数据报的大小限制在64k内 c.因无连接,是不可靠协议 d.不需要建立连接,速度快 TCP a.建立连接,形成传输数据通道 b.在连接中进行大数据传输 c.通过三次握手完成连接,是可靠协议 d.必须建立连接,速度稍慢 三次握手 a.第一次握手,建立连接,客户端发送syn包,到服务器,进入SYN_SENT状态,等待服务器确认 b.第二次握手,服务器收到syn包,必须确认客户端的SYN,同时自己也发送一个SYN+ACK包,服务器进入SYN_RECV状态 c.第三次握手,客户端收到服务器的SYN+ACK包,像服务器发送确认包ACK,此包发送完毕,客户端进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
Socket
- Socket就是为了网络服务提供的一种机制
- 通信的两端都有Socket
- 网络通信其实就是Socket间的通信
- 数据在两个Socket间通过IO传输
UDP代码展示
class SendMessageTask implements Runnable {
@Override
public void run() {
try {
DatagramSocket datagramSocket = new DatagramSocket(Demo.CLIENT_PORT);
byte[] infos = "hello world".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(infos, infos.length,
InetAddress.getByName(Demo.SERVER_HOST), Demo.SERVER_PORT);
datagramSocket.send(datagramPacket);
datagramSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ReceiveMessageTask implements Runnable {
@Override
public void run() {
try {
DatagramSocket datagramSocket = new DatagramSocket(Demo.SERVER_PORT);
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
datagramSocket.receive(datagramPacket);
InetAddress inetAddress = datagramPacket.getAddress();
String ip = inetAddress.getHostAddress();
int port = datagramPacket.getPort();
byte[] contentBytes = datagramPacket.getData();
int contentLength = datagramPacket.getLength();
String content = new String(contentBytes, 0, contentLength);
System.out.println(ip + ":" + port + " ---> " + content);
datagramSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
TCP代码展示
class ClientTask implements Runnable {
@Override
public void run() {
try {
Socket socket = new Socket(Demo.SERVER_HOST, Demo.SERVER_PORT);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello world".getBytes());
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int length = inputStream.read(bytes);
String content = new String(bytes, 0, length);
System.out.println("客户端收到来自服务端的反馈 ---> " + Demo.SERVER_HOST + ":" + Demo.SERVER_PORT + " ----> " + content);
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ServerTask implements Runnable {
@Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(Demo.SERVER_PORT);
Socket socket = serverSocket.accept();
String hostname = socket.getInetAddress().getHostAddress();
int port = socket.getPort();
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int length = inputStream.read(bytes);
String content = new String(bytes, 0, length);
System.out.println("服务端收到来自客户端的消息 ---> " + hostname + ":" + port + " ----> " + content);
OutputStream outputStream = socket.getOutputStream();
String responseContent = "hello java";
outputStream.write(responseContent.getBytes());
socket.close();
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
|