1. 网络编程介绍
1.1 初始网络编程





1.2 网络编程三要素


1.2.1 IP








InetAddress 的使用
java
package com.itheima.Inetaddress;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddressDemo1 {
/*
static InetAddress getByName(String host) 确定主机名称的IP地址, 主机名称可以是机器名称, 也可以是IP地址
String getHostName() 获取此IP地址的主机名
String getHostAddress() 返回文本显示中的IP地址字符串
*/
public static void main(String[] args) throws UnknownHostException {
// 1. 获取InetAddress的对象 -- IP的对象 --> 一台电脑的对象
InetAddress address = InetAddress.getByName("联想小新笔记本");
System.out.println(address);
String name = address.getHostName();
System.out.println(name);
String ip = address.getHostAddress();
System.out.println(ip);
}
}

1.2.2 端口号

1.2.3 协议


(1) UDP协议 (发送数据)

java
package com.itheima.udp;
import java.io.IOException;
import java.net.*;
public class SendMessageDemo {
/*
发送数据
1. 创建DatagramSocket对象(快递公司)
细节:
绑定端口, 以后通过这个端口往外发送
空参: 所有可用的端口中随机一个进行使用
有参: 指定端口号进行绑定
2. 打包数据
3. 发送数据
4. 释放资源
*/
public static void main(String[] args) throws IOException {
// 1. 创建DatagramSocket对象(快递公司)
DatagramSocket ds = new DatagramSocket();
// 2. 打包数据
String str = "你好威呀!!!";
byte[] bytes = str.getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 10086;
DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);
// 3. 发送数据
ds.send(dp);
// 4. 释放资源
ds.close();
}
}
因UDP协议是面向无连接的, 只顾发出, 不考虑是否被正确接收.
(2) UDP协议 (接收数据)

java
package com.itheima.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class ReceiveMessageDemo {
/*
接收数据:
1. 创建DatagramSocket对象(快递公司)
细节:
1. 接收的时候, 一定要绑定端口
2. 绑定的端口, 一定要跟发送的端口保持一致
3. 解析数据包
4. 释放资源
*/
public static void main(String[] args) throws IOException {
// 1. 创建DatagramSocket对象(快递公司)
DatagramSocket ds = new DatagramSocket(10086);
// 2. 接收数据包
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
// 该方法时阻塞的, 程序在执行到这一步时, 会一直在这里死等, 等发送端发送消息
System.out.println(111111);
ds.receive(dp);
System.out.println(2222);
// 3. 解析数据包
byte[] data = dp.getData();
int len = dp.getLength();
InetAddress address = dp.getAddress();
int port = dp.getPort();
System.out.println("接收到数据" + new String(data, 0, len));
System.out.println("该数据是从" + address + "这台电脑中的" + port + "这个端口发出的");
// 4. 释放资源
ds.close();
}
}

(3) UDP协议 (聊天室)
java
package com.itheima.udpdemo2;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveMessageDemo {
/*
按照下面的要求实现程序
UDP发送数据: 数据来自于键盘录入, 直到输入的数据是886, 发送数据结束
UDP接收数据: 因为接受端不知道发送端什么时候停止发送, 故采用死循环接收
*/
public static void main(String[] args) throws IOException {
// 1. 创建DatagramSocket的对象
DatagramSocket ds = new DatagramSocket(10086);
// 2. 接收数据包
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
while (true) {
ds.receive(dp);
// 3. 解析数据包
byte[] data = dp.getData();
int len = dp.getLength();
String ip = dp.getAddress().getHostAddress();
String name = dp.getAddress().getHostName();
// 4. 打印数据
System.out.println("ip为: " + ip + ", 主机名为: " + name + "的人, 发送了数据: " + new String(data, 0, len));
}
}
}

1.3 UDP三种通讯方式
① 单播: 一对一
② 组播: 一对多
③ 广播: 可以给局域网中所有的电脑发送数据

java
package com.itheima.udpdemo3;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class SendMessageDemo {
/*
组播发送端代码
*/
public static void main(String[] args) throws IOException {
// 1. 创建MulticastSocket的对象
MulticastSocket ms = new MulticastSocket();
// 2. 打包数据
String str = "你好你好!";
byte[] bytes = str.getBytes();
InetAddress address = InetAddress.getByName("224.0.0.1");
int port = 10000;
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
// 3. 发送数据
ms.send(dp);
// 4. 释放资源
ms.close();
}
}
java
package com.itheima.udpdemo3;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class ReceiveMessageDemo1 {
/*
组播接收端代码
*/
public static void main(String[] args) throws IOException {
// 1. 创建MulticastSocket的对象
MulticastSocket ms = new MulticastSocket(10000);
// 2. 将当前本机, 添加到224.0.0.1的这一组当中
InetAddress address = InetAddress.getByName("224.0.0.1");
ms.joinGroup(address);
// 3. 创建DatagramPacket数据包对象
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
// 4. 接受数据
ms.receive(dp);
// 5. 解析数据包
byte[] data = dp.getData();
int len = dp.getLength();
String ip = dp.getAddress().getHostAddress();
String name = dp.getAddress().getHostName();
// 打印数据
System.out.println("ip为: " + ip + ", 主机名为: " + name + "的人, 发送了数据: " + new String(data, 0, len));
// 6. 释放资源
ms.close();
}
}

1.4 TCP 通信程序


java
package com.itheima.tcpdemo;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
/*
TCP协议, 发送数据
1. 创建Socket对象
细节:
在创建对象的同时会连接服务器
若连接不上, 代码会报错
*/
public static void main(String[] args) throws IOException {
// 1. 创建Socket对象
Socket socket = new Socket("127.0.0.1",10000);
// 2. 可以从连接通道中获取输出流
OutputStream os = socket.getOutputStream();
// 写出数据
os.write("你好你好啊".getBytes()); // 一个字符占3个字节, 共12个字节
// 3. 释放资源
os.close();
socket.close();
}
}
java
package com.itheima.tcpdemo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
/*
TCP协议, 接收数据
*/
public static void main(String[] args) throws IOException {
// 1. 创建Socket对象
ServerSocket ss = new ServerSocket(10000);
// 2. 监听客户端的连接
Socket socket = ss.accept();
// 3. 从连接通道中获取输入流读取数据(字节流)
/*InputStream is = socket.getInputStream();
// 将字节流转换成字符流isr
InputStreamReader isr = new InputStreamReader(is);
// 包一个缓冲流提升读取效率
BufferedReader br = new BufferedReader(isr);*/
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int b;
while ((b = br.read()) != -1){
System.out.print((char) b);
}
// 4. 释放资源
socket.close(); // 相当于断开跟客户端的连接
ss.close(); // 相当于关闭服务器
}
}

1.5 三次握手和四次挥手


