什么是网络编程
在网络通信协议下,实现网络互联的不同计算机上运行的程序可以进行资源交换,就是用户之间可以发送消息或文件
网络编程三要素
Ip 地址
Ip 地址是网络中设备的唯一标识,分为Ipv4 和 Ipv6 两大类,我们使用Ipv4 进行网络通信,他采用点分十进制表示法,一般长这样
192.168.99.1 ,127.0.0.1 可以代表本机地址,一般用于测试。
|命令|说明 |
|-ipconfig-|-查看Ip-|
| ping IP | 检查网络是否连通 |
端口
网络的通信本质上是两个应用程序的通信,每台计算机上有许多程序,每个程序都运行在某一个端口上,端口号可以作为应用程序的唯一标识,普通应用程序要使用1024 之后的端口号
协议
在计算机网络中,连接和通信的规则称为网络通信协议,它对数据的传输格式,传输速率。传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换,常见的协议有TCP 协议和 UDP 协议
TCP 协议是面向连接的通信协议,可以为两台计算机提供可靠无差别的数据传输,在TCP 协议中必须明确客户端与服务器,由客户端向服务器发起连接请求,每次连接要经过三次挥手。
UDP 协议是面向无连接的通信协议,不管对方有没有收到,反正只负责发出去,由于UDP 耗费资源小,通信效率高,通常会用于传输音频,视频,和普通数据以及直播。
关于三次握手,四次挥手的理解
三次握手以及四次挥手其实确保客户端和服务器知道彼此都具备接收和发送数据的能力,以及做好了分开的准备,其中,以三次挥手为例。
客户端发起连接请求,服务器知道客户端有发送数据的能力,但是不知道客户端有没有接收的能力,与此同时,客户端不知道服务器是否具备接收和发送数据的能力。
服务器回送响应,客户端知道服务器有了接受和发送数据的能力
客户端发送确认信息,服务器知道客户端接收了上次的响应,服务器知道客户端有了接收数据的能力
InetAddress 的使用
inetAddress 是Java 提供的一个类,方便我们对IP 地址进行获取和操作
package com.jj;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Demo {
public static void main(String[] args) throws UnknownHostException {
// 通过主机名或者 IP 地址获取 对象
InetAddress addresses = InetAddress.getByName("192.168.2.20");
// 获取主机名
String hostName = addresses.getHostName();
System.out.println("hostName = " + hostName);
//获取IP 地址的字符串
String Ip = addresses.getHostAddress();
System.out.println("Ip = " + Ip);
}
}
UDP 发送数据
Java 提供了DatagramSocket 类基于 UDPP 协议的Socket
发送数据的步骤:
package com.jj;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
public class Demo {
public static void main(String[] args) throws IOException {
// 定义主机名字
String hostNome ="192.168.6.20";
//定义端口号
int port = 5545;
//创建 socket 对象
DatagramSocket socket = new DatagramSocket();
// 准备发送的数据,控制台读取
System.out.println("请输入你要发送的内容");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
//按行读取
String text = reader.readLine();
//获取字节
byte[] data = text.getBytes();
//将数据打包
DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName(hostNome), port);
//发送数据
socket.send(packet);
// 关闭
socket.close();
}
}
UDP 接收数据
接收数据的步骤:
创建接收端的Socket 对象
创建一个数据报,用于接收数据
调用DatagramSocket 对象的方法接收数据
解析数据包,并数据在控制台显示
关闭接收端
package com.jj;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Main {
public static void main(String[] args) throws IOException {
//UDP 接收只需要知道端口号就可以
int port =5545;
// 创建socket 对象
DatagramSocket socket = new DatagramSocket(port);
// 创建一个数据包接收数据
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
//调用方法接收数据,阻塞等待
socket.receive(packet);
//解析数据包
byte[] data = packet.getData();
int length = packet.getLength();
//这里指定长度是消除后面的空字符,因为有时候不够1024
String dataString = new String(data, 0, length);
System.out.println("收到 = " + dataString);
//关闭
socket.close();
}
}
TCP 客户端发送数据
客户端和服务端会建立虚拟链路,是通过这个虚拟链路进行通信的,Java 对基于tcp 协议的网络提供了良好的封装,使用Socket 对象来代表两端的通信端口,并通过Socket 产生IO 流来进行网络通信
发送数据的步骤
package com.jj;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Tcp {
public static void main(String[] args) throws IOException {
String hostName ="192.168.2.20";
int port = 5566;
// 创建客户端对象
Socket socket = new Socket(hostName, port);
//获取输出流 写数据
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello".getBytes());
// 通知服务端 ,我传输完了
socket.shutdownInput();
//得到服务器反馈
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
String dataString = new String(bytes,0, len);
//接收到的服务器
System.out.println("dataString = " + dataString);
//关流
socket.close();
}
}
TCP 服务器接收发送数据
package com.jj;
//import com.sun.org.apache.xpath.internal.operations.String;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class Tcp1 {
public static void main(String[] args) throws IOException {
// 创建 service 对象
ServerSocket socket = new ServerSocket(7777);
//监听 socket 的连接
Socket accept = socket.accept();
//获取输入流,读数据
InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
//一种是读字节,另一种是读字节数组,文本东西比较少
int len = inputStream.read();
String dataString = new String(bytes, 0, len);
System.out.println("接收客户端到 = " + dataString);
//返回信息
OutputStream outputStream = accept.getOutputStream();
outputStream.write("已接收到的".getBytes());
//关闭资源
socket.close();
accept.close();
}
}
TCP 中socket 的补充
服务器可以通过accept 方法获取道连接的socket ,这个socket 可以获取输入流(客服端传到服务器的信息),然后将输入流写入字符数组,同时这个accept 得到的socket 对象也可以获取输出流,用同意的套路去给客户写东西,客户端的socket 使用
socket.getInputStrem()方法,使用同样的套路去获取服务器的信息。