网络编程顾名思义就是编写能够进行网络数据交互的应用程序。
网络编程三要素
在学习网络编程之前我们必须了解一些有关网络的一些关键词。
【ip地址】
ip地址用来标识网络中的一台主机,在同一个局域网中ip地址不能重复。
分为ipv4和ipv6
- IpV4: 4个字节 4*8=32位
如:192.168.1.11
- IpV6: 16个字节 16*8=128位
如:fe80::2ca8:cc7e:bef0:a1cf%12
注意:如果自己的电脑没有连接互联网或者局域网,
可以使用127.0.0.1地址用于测试学习,这个地址可以用于本机和本机进行通讯。
【端口号】
表示一台主机上的某一个程序,用一个整数表示
【网络协议】
表示在网络中数据通信的规则
UDP: 面向无连接的,不可靠的网络协议,效率高
TCP: 面向有连接,可靠的网络协议,效率低
InetAddress类
先学习一个表示IP地址的类InetAddress,该类中提供了一些方法用于获取主机名或者主机地址。
public static InetAddress getByName(String host)
根据主机名或者ip地址,获取InetAddress对象
public String getHostAddress()
获取主机ip地址
public String getHostName()
获取主机名称
演示上面方法的使用
public class InetAddressDemo {
public static void main(String[] args){
//获取InetAddress对象
InetAddress address = InetAddress.getByName("192.168.31.130");
System.out.println(address);
//获取ip地址
String hostAddress = address.getHostAddress();
System.out.println(hostAddress);
//获取主机名
String hostName = address.getHostName();
System.out.println(hostName);
}
}
UDP通信
UDP通信是面向无连接的数据报协议。Java支持UDP协议的网络通信,需要使用DatagramSocket和DatagramPacket两个类来实现。
DatagramSocket:
用于发送数据和接收数据的一个端点(类似于邮局)
DatagramPacket:
用于封装数据的数据报(类似于快递包裹)
封装的数据有:
字节数组(包裹内容)
数组长度(包裹重量)
对方的ip地址(收件人邮政编码)
对方的端口号(收件人电话号码)
UDP发送端
public class Sender{
public static void main(String[] args){
//1)创建能发送数据的对象DatagramScoket
DatagramScoket ds=new DatagramSocket();
//2)创建数据包DategramPacket
String str="我肚子饿了,给我来一盘酸菜";
byte[] bs=str.getBytes();
DatagramPacket dp=new DatagramPacket(
bs,
bs.length,
InetAddress.getByName("127.0.0.1"),
9000);
//3)发送数据
ds.send(dp);
//4)关闭资源
ds.close();
}
}
UDP接收端
/*
注意事项:
1,发送端DatagramPacket的端口号和接收端DatagramSocket绑定的端口号必须一样
2,端口号不能重复绑定。
*/
public class Reveiver{
public static void main(String[] args){
//1)创建能接收数据的对象DatagramScoket,绑定端口:9000
DategramScoket ds=new DategramSocket(9000);
//2)接收数据
//准备用于接收数据的数据包对象
byte[] bs=new byte[1024];
DatagramPacket dp=new DatagramPacket(bs,bs.length);
ds.receive(dp);
//3)解析数据
InetAddress address=dp.getInetAddress();// 获取ip地址对象
byte[] data=dp.getData();// 获取数据包中的数据
int length=dp.getLength(); //获取有效的字节长度
int port=dp.getPort(); //获取端口号
//4)关闭资源
ds.close();
}
}
把上面代码写好之后,必须先运行接收端,再运行发送端。接收端执行到receive方法时会进去阻塞状态,等待发送端使用send方法发送数据,一旦数据发送了,接收端就会从阻塞的地方继续执行。
TCP通信
TCP通信需要有客户端和服务端,只有在客户端开启的情况下,客户端才能连接服务端。 客户端用Socket表示,服务端用ServerSocket表示。它们之间进行数据交互是通过流来交互的。客户端和服务端进行数据交互都是通过IO流实现的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hx3brWKN-1591172328921)(assets/1585124213442.png)]
TCP客户端
public class Client{
public static void main(String[] args){
//1) 创建连接(客户端 去连接 服务器)
Socket socket=new Socket("127.0.0.1",8000);
//2) 获取输出流对象
OutputStream out=socket.getOutputStream();
//3) 往服务器写数据
out.write("HelloWorld".getBytes());
//4) 读取服务端发过来的数据
InputStream in=socket.getInputStream();
byte[] bytes=new byte[1024];
in.read(bytes);
//5) 关闭资源
socket.close();
}
}
TCP服务端
public class Server{
public static void main(String[] args){
//1) 创建服务端ServerSocket
ServerSocket server=new ServerSocket(8000);
//2) 监听获取客户端Socket
Socket socket=server.accept();
//3) 获取输入流,读取客户端数据
InputStream in=socket.getInputStream();
byte[] bytes=new byte[1024];
in.read(bytes);
//4) 获取输出流对象,往客户端写数据
OutputStream out=socket.getOutputStream();
out.write("写数据给客户端".getBytes());
//4) 关闭资源
socket.close();
}
}
TCP通信必须先开启服务端,服务端代码执行到accpet方法时就会进入阻塞状态,等待客户端过来链接,当客户端和服务端链接了链接,就继续往下执行读取客户端发过来的数据。