网络编程三要素,IP是电脑的地址,端口号是程序的标识,通过IP和端口确定网络传输对象,传输的内容需要遵从协议;
IP是唯一的,IP表示采用IPV4,IPV6两种方法;
采用32位地址长度,分成四组,采用点分十进制表示法,每组最大值为255,但最多只能容纳256*256*256*256=42亿,即最多只能容纳不到43亿的设备;容纳的设备数太少;鉴于此推出了IPV6
IPV6采用128位地址长度,分成八组;可以容纳2^128个IP;采用冒分十六进制表示法;
IPV4分为公网地址(万维网)和私有地址(局域网);以此实现多个设备共用一个IP,它的原理是多个设备共用一个公网地址,再通过路由器为每个设备分配局域网地址,因此在不同的地方,局域网是不同的。
使用特殊IP,可以向本机传输信息,在任何场景下都正确。
ipconfig可以查看本机的IP地址,ping命令可以向其他设备传输信息
最后一个图使用特殊地址向本机传输。
使用静态方法getByName获取对象,参数为设备IP,或者设备名称,设备名称在系统->系统信息内的设备规格中查询
- InetAddress address= InetAddress.getByName("192.168.168.1");
- //参数为设备IP,或者设备名称,设备名称在系统->系统信息内的设备规格中查询
使用getHostName,getHostAddress可以获取address对象的主机名,IP
- System.out.println(address.getHostName());
- System.out.println(address.getHostAddress());
端口号是程序在设备里的唯一标识;端口是由两个字节表示的整数,取值0~65535,其中0~1023的端口号用于一些知名的网络服务或应用,自己的则需要使用1024以上的端口号;一个端口号只能被一个应用程序使用。
计算机网络中,传输数据的规则称为协议;
对osi做出了合并简化,分为应用层,传输层,网络层,物理链路层
UDP协议与TCP协议;
UDP不会检查两个电脑是否连接,直接发送 ;应用于视频语音通话等,丢失数据的后果并不严重的场景,而TCP则用于传输文件等场景。
使用DatagramSocket对象作为发送载体;DatagramPacket将终端应用,发送内容打包,传给DatagramSocket对象,DatagramSocket对象调用send方法发送,
发送内容应该是字节数组,程序流程如下:
- //发送内容
- String stl="abcdefghijklmn";
- byte[]bytes1=stl.getBytes();
- //发送终端,包括IP和端口,这里是接收方的值
- InetAddress address3=InetAddress.getByName("127.0.0.1");
- int port1=10087;
- //使用DatagramPacket打包,
- DatagramPacket dp1=new DatagramPacket(bytes1,bytes1.length,address3,port1);
- DatagramSocket ds2=new DatagramSocket();
- //使用DatagramSocket的send方法发送
- ds2.send(dp1) ;
-
- //释放资源
- ds2.close();
在运行时应该向运行接收端,在运行发送端;
- //接收时要绑定端口;不同于发送;
- DatagramSocket ds4=new DatagramSocket(10087);
- //接收数据包
- byte[]bytes3=new byte[1024];
- DatagramPacket dp2=new DatagramPacket(bytes3,bytes3.length);
- //开始接收
- ds4.receive(dp2);
- //解析数据包
- byte[]data=dp2.getData();
- int len=dp2.getLength();
- InetAddress address4=dp2.getAddress();
- int port3=dp2.getPort();
- System.out.println("接收到数据"+new String(data,data.length));
- System.out.println("该数据是从"+address4+"这台电脑中的"+port3+"这个端口发出的");
-
- //释放资源
- ds4.close();
接收端的receive方法在没接收消息前一直在阻塞态,直到接收完成;
单播,广播,组播
组播:组播的IP地址,代表了一组电脑,发给组播就是发给这些电脑;组播使用相同的端口和IP地址
广播:
组播,广播,单播通过不同的IP地址实现
- MulticastSocket ms=new MulticastSocket(10000);
-
- byte[]bytes=new byte[1024];
- InetAddress ia=InetAddress.getByName("224.0.0.1");
- ms.joinGroup(ia);
- DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
-
- while (true) {
- ms.receive(dp);
- if("884".equals("sss"))break;
- int len=dp.getLength();
- byte[]data=dp.getData();
- String name=dp.getAddress().getHostName();
- String ip=dp.getAddress().getHostAddress();
- System.out.println("地址为"+ip+",名称为"+name+"的主机给你发送了消息: "+new String(data,0,len));
- }
- ms.close();
广播与单播相同,但广播要调用setBroadcast():
Java中的广播是通过使用UDP协议来实现的。首先,我们需要在套接字上调用setBroadcast()方法,以指示套接字要广播数据包。然后,我们可以使用DatagramSocket类来创建一个套接字,并使用DatagramPacket类来创建一个数据包,其中包含要广播的消息。最后,我们通过调用socket.send(packet)方法来发送广播消息。
- public class BroadcastingClient {
- private static DatagramSocket socket = null;
-
- public static void main(String[] args) throws IOException {
- broadcast("Hello", InetAddress.getByName("255.255.255.255"));
- }
-
- public static void broadcast(String broadcastMessage, InetAddress address) throws IOException {
- socket = new DatagramSocket();
- socket.setBroadcast(true);
-
- byte[] buffer = broadcastMessage.getBytes();
- DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, 4445);
- socket.send(packet);
-
- socket.close();
- }
- }
使用输入输出流来传输信息,因此接收,发出的函数是不一样的。
- public class Server {
- public static void main(String[] args) throws IOException {
- //接收端相比于发送端多了一个ServerSocket,用于监听;
- //创建ServerSocket对象
- ServerSocket socket=new ServerSocket(10001);//Socket(10086); 三次握手
-
- //监听客户端的链接
- Socket s =socket.accept();
-
- //程序与端口建立输入流,输入流室是socket自带的;
- InputStream ss=s.getInputStream();
- InputStreamReader is=new InputStreamReader(ss);//按字符来接收,
- BufferedReader br=new BufferedReader(is);
- // BufferedReader bt=new BufferedReader(new
-
- //InputStreamReader(socket.getInputStream()));简写,效果一样
- int b;
- while((b=is.read())!=-1){
- System.out.println((char)b);
- }
-
- //释放资源,断开链接,关闭服务器
- s.close();
- socket.close();//四次挥手
- }
- }
-
-
- public class Client {
- public static void main(String[] args) throws IOException {
- Socket s=new Socket("127.0.0.1",10001); //三次握手协议
-
- OutputStream os=s.getOutputStream();
-
- os.write("aaa".getBytes());
-
- os.close();
- s.close();//四次挥手
-
- }
- }
对于中文Server需要使用转换流转换;
- public class Server {
- public static void main(String[] args) throws IOException {
- ServerSocket ss=new ServerSocket(10001);
-
- //等待链接
- Socket socket=ss.accept();
-
- InputStream is=socket.getInputStream();
- InputStreamReader isr=new InputStreamReader(is);
- int b;
- while((b=isr.read())!=-1)
- {
- System.out.println((char)b);
- }
- socket.close();
- ss.close();
- }
- }
三次握手:客户端发送连接请求->服务器返回响应->客户端再次发出确认信息,建立连接;
四次挥手
客户端发出取消连接请求->服务器返回响应,表示受到请求->服务器处理完数据后,发出确认取消消息->客户端再次发送确认消息,连接取消