什么是网络编程?
Java网络编程是一种使用Java编程语言编写网络应用程序的方法。它使开发人员能够使用Java API来创建、连接和通信网络上的应用程序。Java网络编程涉及创建套接字(socket),建立TCP/IP连接,发送和接收数据,并通过网络传输信息。Java网络编程还可以用于构建客户端/服务器应用程序和分布式应用程序。在Java网络编程中,应用程序可以使用Java Socket类或Java NIO(非阻塞I/O)库来与远程主机进行通信。
基础知识
网络三要素:IP、端口、协议
IP:IP指网际互连协议,Internet Protocol的缩写,是TCP/IP体系中的网络层协议。
端口:是设备与外界通讯交流的出口。
协议:是对数据格式和计算机之间交换数据时必须遵守的规则的正式描述。
例如:
127.0.0.1:8080
其中127.0.0.1为ip地址
8080为端口号
IP
IP是为上网设备分发的一种特定格式的地址,每一台机器的ip地址都不相同。
IP地址的版本分为:ipv4、ipv6
IPv4:Internet Protocol version 4,是使用的是32位(4个字节)的地址。因此只有4294967286个地址,其中一些地址由于特殊用途而保留,如专用网络(约1800万个)和多播地址(2.7亿个),这减少了可在互联网上路由的地址数量。随着地址不断被分配给用户,IPv4地址枯竭问题也在随之产生。基于分类网络、无类别域间路由和网络地址转换的地址结构重构显著地减少了地址枯竭的速度。
私有地址(Private address)属于非注册地址,专门为组织机构内部使用。
以下列出留用的内部私有地址
A类 10.0.0.0--10.255.255.255
B类 172.16.0.0--172.31.255.255
C类 192.168.0.0--192.168.255.255
IPv6:Internet Protocol Version 6,是使用128位(16个字节)的地址。作用域IPv4相同。
端口
网络技术中的端口默认指的是TCP/IP协议中的服务端口,一共有0-65535个端口,比如我们最常见的端口是80端口,默认访问网站的端口就是80,会发现浏览器默认把80去掉,就是因为这是个默认端口,所以没必要再显示出来,还有用于ftp文件传输的21端口,我们知道一台主机通常可以提供网页服务,ftp服务,邮件的SMTP服务等,都是可以同时在一个ip上进行的,那为什么不会造成混乱呢,原因就是通过ip+端口来区分这些服务,让每个端口有自己的分工,又能同时使用一个ip地址。
协议
网络通信中一般使用的都是TCP/IP协议,TCP/IP是由一组具有专业用途的多个子协议组合而成的,这些子协议包括TCP、IP、UDP、ARP、ICMP等。TCP/IP凭借其实现成本低、在多平台间通信安全可靠以及可路由性等优势迅速发展,并成为Internet中的标准协议。在上世纪90年代,TCP/IP已经成为局域网中的首选协议,在最新的操作系统(如Windows7、Windows XP、Windows Server2003等)中已经将TCP/IP作为其默认安装的通信协议。
TCP(Transmission Control Protocol)
控制传输协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。
三次握手、四次挥手。
UDP(User Datagram Protocol)
用户数据报协议,是一种无连接的传输协议
Java实现
UDP
由于UDP是基于无连接的,因此,只需要设置IP地址以及端口号就可以完成通信。
发送端
//创建DatagramSocket
DatagramSocket ds = new DatagramSocket();
String meg = "";
//打包数据
Scanner scanner = new Scanner(System.in);
while(!meg.equals("886"))
{
System.out.println("输入要说的话:");
meg = scanner.nextLine();
byte[] bytes = meg.getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 10086;
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
//发送信息
ds.send(dp);
}
//关闭流
ds.close();
使用DatagramSocket发送数据。
InetAddress.getByName("127.0.0.1")可以通过主机名称或者ip地址来获取目标ip。
使用DatagramPackage()来初始化数据包。
参数:
- 参数1:发送数据字节
- 参数2:发送数据长度
- 参数3:目标ip地址
- 参数4:目标端口
然后使用send()发送。
接收端
DatagramSocketds ds = newDatagramSocket(10086);
//2.接收数据包
byte[] bytes = newbyte[1024];
DatagramPacket dp = newDatagramPacket(bytes, bytes.length);
ds.receive(dp);
//3.解析数据包
byte[] data = dp.getData();
intlength = dp.getLength();
InetAddress address = dp.getAddress();
int port = dp.getPort();
System.out.println("接收到的数据:" + newString(data, 0, length));
System.out.println("数据是从:" + address + "地址:" + port + "端口发出的");
//4.释放资源
ds.close();
创建DatagramSocket用于接收
创建DatagramPackage管理接收数据大小
然后使用get函数就可以获取到内容。
组播
发送端
//创建 MulticastSocket
MulticastSocket ms = new MulticastSocket(10000);
//创建数据包
String s = "你好!";
byte[] bytes = s.getBytes();
InetAddress address = InetAddress.getByName("224.0.0.1");//组播地址
int port = 10000;
DatagramPacket dp = new DatagramPacket(bytes,bytes.length,address,port);
//发送
ms.send(dp);
//释放
ms.close();
组播创建的是MulticastSocket剩余操作都一样
接收端
//创建MulticastSocket
MulticastSocket ms = new MulticastSocket(10000);
//将本机地址加入到224.0.0.1组中
InetAddress address = InetAddress.getByName("224.0.0.1");
ms.joinGroup(address);
//创建接收包
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
//接收数据
ms.receive(dp);
//解析数据
byte[] data = dp.getData();
int length = dp.getLength();
InetAddress ip = dp.getAddress();
int port = dp.getPort();
System.out.println("地址为" + ip + ",端口为" + port + "的用户发送了:" + new String(data, 0, length));
//释放资源
ms.close();
接收端也创建的是MulticastSocket
注意的是:在定义ip后,需要将MulticastSocket对象加入到组中,使用joinGroup(ip)方法。
TCP
tcp分为客户端和服务器
客户端
//创建Socket对象
Socket socket = new Socket("127.0.0.1",10086);
//获取输出流
OutputStream outputStream = socket.getOutputStream();
//发送数据
outputStream.write("你好你好".getBytes());
//释放资源
outputStream.close();
socket.close();
在创建Socket对象的时候设置ip和端口,然后利用输出流来实现对数据的发送,在服务器用输入流来实现接收,完成后需要释放资源。
服务器
//创建客户端对象
ServerSocket ss = new ServerSocket(10086);
//监听客户端连接
Socket accept = ss.accept();
//从连接通道中获取数据
InputStream is = accept.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
int b;
while ((b = br.read()) != -1) {
System.out.print((char) b);
}
//释放资源
accept.close();
ss.close();
服务器端绑定端口即可,通过accept()来监听连接,然后接收数据,最后要释放资源。