前言
这篇文章我觉得我对于网络基础部分就不用再说更多了,直接一张图就够。剩下的用代码和注释来说明,看懂就是学会。
单播通信
TCP通信
服务端
public class Sever {
public static void main(String[] args) {
ServerSocket serverSocket = null; //初始化定义为空保证安全
Socket socket = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
//创建ServerSocket对象,监听9999端口
serverSocket = new ServerSocket(9999);
//等待客户端的连接请求,返回一个Socket对象,程序阻塞在此处直到有客户端连接
socket = serverSocket.accept();
//获取输入流,用于读取客户端发送的数据
is = socket.getInputStream();
//创建字节数组输出流,用于存储读取到的数据
baos = new ByteArrayOutputStream();
//预定义缓冲区数组大小,方便存储数据
byte[] buffer = new byte[1024];
int len;
//循环读取客户端发送的数据,将数据存储到字节数组输出流中
while((len = is.read(buffer))!=-1){
//要写入的字节数组,从第一个元素开始写入,写入的字节数量
baos.write(buffer,0,len);
}
//将字节数组输出流中的数据转换为字符串并输出到控制台
System.out.println(baos.toString());
//关闭字节数组输出流和输入流
baos.close();
is.close();
//关闭Socket对象和ServerSocket对象
socket.close();
serverSocket.close();
} catch (IOException e){
e.printStackTrace(); //打印异常信息
}
}
}
客户端
public class Cilent {
public static void main(String[] args) {
Socket socket = null; // 用于建立客户端与服务器之间的套接字连接
OutputStream os = null; // 用于向服务器发送数据的输出流
try {
// 通过IP地址获取服务器的InetAddress实例
InetAddress serverIP = InetAddress.getByName("127.0.0.1");
int port = 9999; // 连接服务器的端口号
// 创建套接字连接至服务器
socket = new Socket(serverIP, port);
// 通过套接字获取输出流,用于向服务器发送数据
os = socket.getOutputStream();
// 向服务器发送数据,需要
os.write("Hello, world!".getBytes());
//getBytes()方法编码为 byte 序列,并将结果存储到一个新的 byte 数组中
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close(); // 关闭套接字连接
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
UDP通信
服务端
public class Sever {
public static void main(String[] args) throws Exception {
//创建DatagramSocket对象,监听6666端口
DatagramSocket socket = new DatagramSocket(6666);
//一直循环接收信息
while (true) {
byte[] container = new byte[1024];
//创建DatagramPacket对象,用于接收客户端发送的数据(合成一个包)
DatagramPacket packet = new DatagramPacket(container,0,container.length);
//要发送或接收的数据的字节数组,从头开始读取或写入,读取或写入的字节数
//接收客户端发送的数据
socket.receive(packet);
byte[] data = packet.getData();
//获取接收到的数据,返回一个字节数组
//将接收到的字节数组(包)转换为字符串
String receiveDatas = new String(data,0,packet.getLength());
System.out.println(receiveDatas);
//判断是否输入了“bye”,如果是则退出循环
if (receiveDatas.trim().equals("bye")) {
break;
}
}
//关闭DatagramSocket对象
socket.close();
}
}
客户端
public class Cilent {
public static void main(String[] args) throws Exception {
try {
//创建DatagramSocket对象,监听8888端口
DatagramSocket socket = new DatagramSocket(8888);
//创建BufferedReader对象,用于从控制台读取数据
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
//一直循环接收信息
while (true) {
//从控制台读取数据
String data = reader.readLine();
//将读取到的字符串转换为字节数组
byte[] datas = data.getBytes();
//创建DatagramPacket对象,打包好数据,指定发送的目标地址和端口号
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("127.0.0.1",6666));
//发送数据
socket.send(packet);
//判断是否输入了“bye”,如果是则退出循环
if (data.equals("bye")) {
break;
}
}
//关闭DatagramSocket对象
socket.close();
} catch (SocketException e) {
e.printStackTrace();
}
}
}
多线程通信
服务端
//继承Runnable接口
public class Sever implements Runnable {
DatagramSocket socket = new DatagramSocket(6666);
private int port;
private String msgfrom;
public Sever(int port,String msgfrom) throws IOException {
this.port = port;
this.msgfrom = msgfrom;
socket = new DatagramSocket(6666);
}
//重写run()方法
public void run() {
try {
while (true) {
byte[] container = new byte[1024];
//创建DatagramPacket对象,用于接收客户端发送的数据
DatagramPacket packet = new DatagramPacket(container,0,container.length);
//接收客户端发送的数据
socket.receive(packet);
byte[] data = packet.getData();
//将接收到的字节数组转换为字符串
String receiveDatas = new String(data,0,data.length);
System.out.println(msgfrom + ":" + receiveDatas);
//判断是否输入了“bye”,如果是则退出循环
//trim()去除首尾空格,equals()比较对象,被比较的放前面
if (receiveDatas.trim().equals("bye")) {
break;
}
}
//关闭DatagramSocket对象
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
public class Cilent implements Runnable {
DatagramSocket socket = null;
BufferedReader reader = null;
private String toIP;
private int fromport;
private int toport;
public Cilent(int fromIP,String toIP,int toport) throws SocketException {
this.fromport = fromport;
this.toport = toport;
this.toIP = toIP;
//创建DatagramSocket对象,监听指定端口
socket = new DatagramSocket(fromport);
//创建BufferedReader对象,用于从控制台读取数据
reader = new BufferedReader(new InputStreamReader(System.in));
}
public void run() {
try {
while (true) {
//从控制台读取数据
String data = reader.readLine();
//将读取到的字符串转换为字节数组
byte[] datas = data.getBytes();
//创建DatagramPacket对象,指定发送的目标地址和端口号
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIP,this.toport));
//发送数据
socket.send(packet);
//判断是否输入了“bye”,如果是则退出循环
if (data.equals("bye")) {
break;
}
}
//关闭DatagramSocket对象
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
广播通信
服务端
public class Sever {
public static void main(String args[]) {
int port = 5858;
InetAddress group = null;
MulticastSocket socket = null;
try {
//创建InetAddress对象,指定广播地址
group = InetAddress.getByName("127.0.0.1");
//创建MulticastSocket对象,监听指定端口
socket = new MulticastSocket(port);
//创建InetSocketAddress对象,指定广播地址和端口
InetSocketAddress socketAddress = new InetSocketAddress(group,port);
//获取指定网卡的NetworkInterface对象
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(group);
//加入广播组
socket.joinGroup(socketAddress,networkInterface);
} catch (Exception e) {
e.printStackTrace();
}
while (true) {
byte data[] = new byte[8192];
DatagramPacket packet = null;
//创建DatagramPacket对象,用于接收广播内容
packet = new DatagramPacket(data,data.length,group,port);
try {
socket.receive(packet);
//将接收到的字节数组转换为字符串
String message = new String(packet.getData(),0,packet.getLength());
System.out.println("接收的内容:" + message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
客户端
public class Cilent {
// Broadcast
String s = "abcd";
int port = 8989;
InetAddress group = null;
MulticastSocket socket = null;
Cilent() {
try {
//创建InetAddress对象,指定广播地址(路由器指定的)
group = InetAddress.getByName("255.255.255.255");
//创建MulticastSocket对象,监听指定端口
// (注意,从这里开始DatagramSocket已经变成了MulticastSocket)
socket = new MulticastSocket(port);
//设置TTL值为1,表示只在本地网络中广播,TTL值是该字段指定IP包被路由器丢弃之前允许通过的最大网段数量,1代表只能通过一个网段
socket.setTimeToLive(1);
//创建InetSocketAddress对象,指定广播地址和端口
InetSocketAddress socketAddress = new InetSocketAddress(group,port);
//获取指定网卡的NetworkInterface对象
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(group);
//加入广播组
socket.joinGroup(socketAddress,networkInterface);
} catch (IOException e) {
e.printStackTrace();
}
}
public void play() {
while (true) {
try {
DatagramPacket packet = null;
byte data[] = s.getBytes();
//创建DatagramPacket对象,指定发送的目标地址和端口号
packet = new DatagramPacket(data,data.length,group,port);
System.out.println(new String(data));
//发送数据
socket.send(packet);
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String args[]) {
new Cilent().play();
}
}
多播通信
服务器接收端程序
public class TestMain {
private static MulticastSocket ds; //多播套接字对象
static String multicastHost="239.0.0.255"; //多播组地址
static InetAddress receiveAddress; //接收地址对象
public static void main(String[] args) throws IOException {
// 创建多播套接字,绑定到本地的8899端口
ds = new MulticastSocket(8899);
// 获取多播组地址
receiveAddress=InetAddress.getByName(multicastHost);
// 将套接字加入多播组
ds.joinGroup(receiveAddress);
// 开启一个新线程,并将多播套接字对象传递给udpRunnable对象
new Thread(new udpRunnable(ds)).start();
}
}
class udpRunnable implements Runnable {
MulticastSocket ds;
public udpRunnable(MulticastSocket ds) {
this.ds=ds;
}
public void run() {
// 创建一个用于接收数据的缓冲区
byte buf[] = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
while (true) {
try {
// 从多播套接字中接收数据,并将数据存储到数据包对象中
ds.receive(dp);
// 打印接收到的客户端消息
System.out.println("receive client message : "+new String(buf, 0, dp.getLength()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
客户发送端
public class SendUdp {
public static void main(String[] args) throws IOException {
MulticastSocket ms=null;
DatagramPacket dataPacket = null;
ms = new MulticastSocket();
// 设置多播数据包的生存时间为32
ms.setTimeToLive(32);
// 将字符串 "组播 测试" 转换为字节数组 data
byte[] data = "组播 测试".getBytes();
// 获取多播组地址 address 对象
InetAddress address = InetAddress.getByName("239.0.0.255");
// 创建数据包 dataPacket,指定数据、数据长度、目标地址和端口
dataPacket = new DatagramPacket(data, data.length, address,8899);
// 发送数据包
ms.send(dataPacket);
// 关闭套接字
ms.close();
}
}
IP地址分级
之前比赛写过这个还不是很了解,这里记一下
分类 | 范围 |
---|---|
A | 0.0.0.0-127.255.255.255 |
B | 128.0.0.0-191.255.255.255 |
C | 192.0.0.0-223.255.255.255 |
D | 224.0.0.0-239.255.255.255 |
E | 240.0.0.0-255.255.255.255 |
后记
发现一个网站,大家可以进来玩玩