网络的基本概念
- 连接多台电脑之间的通信的方式就是网络
实现网路通信要指定协议,网络协议中最基础的协议就是网络七层架构协议
tcp/ip协议提出一个ip地址的概念,ip地址就是电脑在网络中的唯一标识
- 在window使用使用ipconfig能查看本机的ip地址
- 可以通过ping验证两台电脑之间网络是否通畅
ipv4和ipv6
ipv4地址 :::info 255.255.255.255 :::
ipv6 :::info FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF :::
域名的概念
- ip地址比较容易记,那么就提出了域名的概念
- 域名本质上是在DNS服务上和IP地址绑定的字符串
端口的概念
InetAddress类,java对IP信息的封装 ```java
InetAddress localHost = InetAddress.getLocalHost(); //本机
System.out.println("本机IP地址:" + localHost.getHostAddress());
System.out.println("本机名称:" + localHost.getHostName());
//根据域名得到InetAddress对象
InetAddress bd = InetAddress.getByName("www.baidu.com");
System.out.println("百度服务器地址:" + bd.getHostAddress());
System.out.println("百度服务器名称:" + bd.getHostName());
//根据IP地址得到InetAddress对象
InetAddress ia = InetAddress.getByName("39.130.131.42");
System.out.println("服务器主机IP:" + ia.getHostAddress());
//如果39.130.131.42IP地址不存在或者DNS(域名解析系统)不允许进行IP地址和域名的映射,就会直接返回域名地址
System.out.println("主机名称" + ia.getHostName());
- <br />
- InetSocketAddress :主要用实现IP和端口的数据的存储
```java
//创建对象
InetSocketAddress is1 = new InetSocketAddress("localhost", 9999);
InetSocketAddress is2 = new InetSocketAddress("127.0.0.1", 9999);
InetSocketAddress is3 = new InetSocketAddress("192.168.136.1", 9999);
InetAddress ia = InetAddress.getByName("192.168.136.1");
InetSocketAddress is4 = new InetSocketAddress(ia, 9999);
System.out.println("主机名称:" + is4.getHostName());
System.out.println("主机IP地址:" + is4.getAddress());
Socket编程
- 建立服务器和客户端之间的连接
- 创建服务器 ```java public static void main(String[] args) throws IOException { //创建服务器,指定端口号,默认绑定本机地址 ServerSocket serverSocket = new ServerSocket(8888); System.out.println(“创建了服务器”); //当前服务器等待其他的客户端进行链接 serverSocket.accept();//会阻塞代码 System.out.println(“有人进来了”); }
- 创建客户端,并且连接服务器
```java
public static void main(String[] args) throws IOException {
//第一个参数是主机的ip,是字符串类型
//127.0.0.1 默认是本机的端口号
//localhost 默认是本机的域名
//第二个参数是端口是int类型
Socket socket = new Socket("localhost",8888);
System.out.println("连接服务器");
}
单向通信
实现服务器代码
//服务器
public class Server {
public static void main(String[] args) throws IOException {
//创建服务器,指定端口号,默认绑定本机地址
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("创建了服务器");
//当前服务器等待其他的客户端进行链接
Socket socket = serverSocket.accept();//会阻塞代码
System.out.println("有人进来了");
//通过一个socket打开一个输入流
InputStream inputStream = socket.getInputStream();
//创建数据
DataInputStream dis = new DataInputStream(inputStream);
String msg = dis.readUTF();//读取string数据
System.out.println("收到来自客户端的消息:"+msg);
}
}
实现客户端代码
//客户端代码
public class Client {
public static void main(String[] args) throws IOException {
//第一个参数是主机的ip,是字符串类型
//127.0.0.1 默认是本机的端口号
//localhost 默认是本机的域名
//第二个参数是端口是int类型
Socket socket = new Socket("localhost",8888);
System.out.println("连接服务器");
//通过socket获取输出流
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
//在控制台输入内容
Scanner scanner = new Scanner(System.in);
dos.writeUTF(scanner.next());
System.out.println("消息发送成功");
os.close();
}
}
双向通信
服务器端,先accpet接收客户端,再接收来自客户端的消息,最后返回消息给客户端
public static void main(String[] args) throws IOException {
//创建服务器,指定端口号,默认绑定本机地址
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("创建了服务器");
//当前服务器等待其他的客户端进行链接
Socket socket = serverSocket.accept();//会阻塞代码
System.out.println("有人进来了");
////////////////////读取数据
//通过一个socket打开一个输入流
InputStream inputStream = socket.getInputStream();
//创建数据
DataInputStream dis = new DataInputStream(inputStream);
String msg = dis.readUTF();//读取string数据
System.out.println("收到来自客户端的消息:"+msg);
////////////////////输出数据
//服务器端返回消息
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
Scanner scanner = new Scanner(System.in);
dos.writeUTF(scanner.next());
}
客户端,连接服务器段,发送消息,最后接收来服务器端的消息 ```java public static void main(String[] args) throws IOException { //第一个参数是主机的ip,是字符串类型 //127.0.0.1 默认是本机的端口号 //localhost 默认是本机的域名 //第二个参数是端口是int类型 Socket socket = new Socket(“localhost”,8888); System.out.println(“连接服务器”);
//////////////////输出数据 //通过socket获取输出流 OutputStream os = socket.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); //在控制台输入内容 Scanner scanner = new Scanner(System.in); dos.writeUTF(scanner.next());//会阻塞代码 System.out.println(“消息发送成功”);
///////////////////////////////
/////////读取数据
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
String result = dis.readUTF(); //会阻塞代码
System.out.println("来自服务器的消息:"+result);
}
- 通过线程实现两者可以随意通信
- 服务器端代码
```java
public class Server {
public static void main(String[] args) throws IOException {
//创建服务器,指定端口号,默认绑定本机地址
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("创建了服务器");
//当前服务器等待其他的客户端进行链接
Socket socket = serverSocket.accept();//会阻塞代码
System.out.println("有人进来了");
////////////////////读取数据
//通过一个socket打开一个输入流
//创建一个线程用户接收数据
Thread thread = new Thread(){
@Override
public void run() {
while (true){
InputStream inputStream = null;
try {
inputStream = socket.getInputStream();
//创建数据
DataInputStream dis = new DataInputStream(inputStream);
String msg = dis.readUTF();//读取string数据
System.out.println("客户端说:"+msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
thread.start();
while(true){
////////////////////输出数据
//服务器端返回消息
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
Scanner scanner = new Scanner(System.in);
dos.writeUTF(scanner.next());
System.out.println("发送消息成功");
}
}
}
客户端代码
//客户端代码
public class Client {
public static void main(String[] args) throws IOException {
//第一个参数是主机的ip,是字符串类型
//127.0.0.1 默认是本机的端口号
//localhost 默认是本机的域名
//第二个参数是端口是int类型
Socket socket = new Socket("localhost",8888);
System.out.println("连接服务器");
///////////////////////////////
/////////读取数据
Thread thread = new Thread(){
@Override
public void run() {
while(true){
InputStream in = null;
try {
in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
String result = dis.readUTF(); //会阻塞代码
System.out.println("服务器说:"+result);
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
thread.start();
while(true){
//////////////////输出数据
//通过socket获取输出流
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
//在控制台输入内容
Scanner scanner = new Scanner(System.in);
dos.writeUTF(scanner.next());//会阻塞代码
System.out.println("消息发送成功");
}
}
}
UDP通信
- TCP(Transmission Control Protocol )传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。不会出现丢包的问题,但是速度相对慢
- UDP(User Datagram Protocol) 用户数据报协议:是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB。会出现丢包的问题,但是速度快
UDP服务器端
public static void main(String[] args) throws IOException {
//创建一个udp的socket
DatagramSocket server = new DatagramSocket(7777);
System.out.println("udp服务器在7777端口启动");
//2有一个空的数据包(缓存),打算用了来接收对方传过来带的数据库包
DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
//接收消息
server.receive(packet); //也会阻塞线程
//直接packet从获取数据
byte[] data = packet.getData();
int len = packet.getLength(); //获取数据的长度
System.out.println("接收的数据:"+new String(data,0,len));
//4,关闭资源
server.close();
}
UPD客户端
public static void main(String[] args) throws IOException {
//创建客户端的socket
DatagramSocket client = new DatagramSocket(6666);
System.out.println("客户端在6666端口启动了");
Scanner scanner = new Scanner(System.in);
String msg = scanner.next();
byte[] data = msg.getBytes(StandardCharsets.UTF_8);
DatagramPacket datagramPacket = new DatagramPacket(
data,//发送的数据
data.length,//发送数据的长度
InetAddress.getByName("localhost"),
7777
);
client.send(datagramPacket);
System.out.println("发送请求成功");
client.close();
}
Http通信
Http属于一种无状态连接
- socket可以双向通信,连接是一致保存的
- http是单项通信,只能是客户端发送请求给服务器端,然后服务器端再返回请求可客户端。连接就结束了
- 服务器端不可以主动发请求给客户端
- http协议的组成
- 两个部分
- 头部
- 正文
- 两个环节
- 请求
- 响应
- 两个部分
基于http协议的编程
- 服务器端不需要自己创建,已经有很成熟的http服务器,例如tomcat
在java中发送http请求
//1,创建一个url对象用于存储发送请求的地址
URL url = new URL("http://www.baidu.com");
//2,打开连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//3,设置请求方式GET POST PUT DELETE
connection.setRequestMethod("GET");
//4,连接服务器
connection.connect();
//5,获取响应结果
InputStream in = connection.getInputStream();
//创建缓存流
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
StringBuilder sb = new StringBuilder();
while((line=br.readLine())!=null){
sb.append(line);
}
System.out.println(sb.toString());
br.close();
in.close();