一.InetAddress
此类是获取网络地址实例的一个类,但是不能通过new 来实例化这个类,因为它没有构造器,但是可以通过组合的方式来使用类中的方法
拿取主机为localhost的网络地址实例
InetAddress address=InetAddress.getByName("localhost");
拿取百度网络地址实例
//拿取主机为www.baidu.com的网络地址实例 InetAddress BaiDu=InetAddress.getByName("www.baidu.com");
通过地址实例拿取详细的地址信息
- 拿取IP地址
//获得真实的IP地址 System.out.println(BaiDu.getCanonicalHostName());
- 拿取主机名称
//获得地址的主机名 or 域名 System.out.println(BaiDu.getHostName());
二.InetSocketAddress
InetSocketAddress也是.net包下的一个类,它的作用是拿取主机的特定端口信息 如拿取百度的80端口信息://拿取百度的80端口信息 InetSocketAddress socketAddress = new InetSocketAddress("www.baidu.com", 80); System.out.println(socketAddress);
通过new关键字可以实例化InetSocketAddress类,从而通过此对象的方法继续拿到其它信息
- 地址信息
//获取地址信息 System.out.println(socketAddress.getAddress());
- 主机信息
//获取主机名称 System.out.println(socketAddress.getHostName());
- 端口信息
//获取端口号 System.out.println(socketAddress.getPort());
三.模拟使用
TCP实现文件上传
模拟两个角色,一个用户端,一个服务器端
用户端负责发送,服务器端负责接收,
- 模拟用户端:
TCP连接需要的参数对方的IP地址和端口
//1.创建一个socket连接 Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),5206);
建立连接以后需要读取文件再发送给服务器端
//2.创建一个文件输出流 OutputStream outs = socket.getOutputStream(); //3.读取文件 FileInputStream file = new FileInputStream(new File("kq.png"));
开始向服务器端写出数据
//4.写出文件 byte[] buffer = new byte[1024]; int len; while ((len=file.read(buffer))!= outs.write(buffer,0,len); } //通知服务器已经完成了传输 socket.shutdownOutput();
等待服务器发送结束标志
//接收服务器端发送的结束标志 InputStream stream = socket.getInputS ByteArrayOutputStream baos = new Byte byte[] bytes = new byte[1024]; int len1; while ((len1=stream.read(buffer))!=-1 baos.write(buffer,0,len1); } System.out.println(baos.toString());
收到服务器发送的接收完成的标志,关闭客户端资源
//关闭资源 file.close(); baos.close(); outs.close(); socket.close();
- 模拟服务器端
创建一个连接,并开启需要使用到的端口
//1.创建服务 ServerSocket serverSocket = new ServerSocket(5206);
阻塞式监听端口,直到有客户端发来连接
//2.监听用户端口 Socket accept = serverSocket.accept();
获取客户端发送的IO流文件
//3.获取输入流 InputStream io = accept.getInputStream(); //4.文件输出流 FileOutputStream file = new FileOutputStream(new File("刻晴.png"));
写出IO流文件内容
byte[] buffer = new byte[1024]; int len; while ((len=io.read(buffer))!=-1){ file.write(buffer,0,len); }
写出完成后,向客户端发送读取完成标志,并关闭资源
//向客户端发送数据读取完成标志OutputStream os = accept.getOutputStream(); os.write("我已经读取完成了".getBytes()); //关闭资源 file.close(); io.close(); accept.close(); serverSocket.close();
UDP实现信息发送
Udp和TCP传输的最大区别在于Udp是无连接的,它传送不像Tcp需要事先预告,而是直接发向目的地址
TCP的传输就好比打电话,在你呼叫的时候可以选择不接,也可以选择接,这就是连接,如果 想和对方通话,那么对方就必须接并且建立联系
UDP的传输就好比发送消息,你不能选择不接收,就算关机,也只是延迟收到,而发送方只管一键发送,并不在乎你是否收到
所以在下面的实现中,是没有连接的过程的,但是还是需要对方的地址和端口,这是目的地必须要知道,只是不需要链接了
- 模拟客户端
建立一个socket对象用来发送报文
//1.建立一个socket,发送报文 DatagramSocket socket = new DatagramSocket();
发送方的信息及内容
//2.发送方信息即数据 String msg="i miss you"; InetAddress address =InetAddress.getByName("localhost"); int port=5206;
打包一个数据包
//3.数据包,数据,数据的长度起始,要发送给谁 DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, address, port);
发送包,完成,关流
//4.发送包 socket.send(packet); //5.关闭流 socket.close();
- 模拟服务器端
开放端口
//开放端口 DatagramSocket socket = new DatagramSocket(5206);
接收并展示数据包
//2.接收数据包 byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length); socket.receive(packet);//阻塞式接收 System.out.println(packet.getAddress()); System.out.println(new String(packet.getData(),0,packet.getLength()));
关闭连接
//3.关闭连接 socket.close();
模拟服务器端接收到的参数
模拟连续对话
使用Udp发消息的基础上,在加上一个循环语句就是可以实现连续对话的
我们模拟的场景是,连续对话也就是一端既要接收数据,又要发送数据
那么我们就可以使用多线程编程,一个线程负责发送消息,一个线程负责接收消息
- 搭建发送的线程类
多线程需要实现Runnable接口,并且重写Run方法
run方法
@Override public void run() { int count=10; while (count>0){ String data = null; //接收数据,控制台读入 sysIn = new BufferedReader(new InputStreamReader(System.in)); try { data = sysIn.readLine(); byte[] dataBytes = data.getBytes(); DatagramPacket packet = new DatagramPacket(dataBytes, 0, dataBytes.length, InetAddress.getByName(ToIP), ToPort); socket.send(packet); count--; if (data.equals("bye")){ break; } } catch (IOException e) { throw new RuntimeException(e); } } //关闭流 socket.close(); }
创立一个socket对象的代码被提升作用域到构造器中了
构造方法
public class UdpTalkSend implements Runnable{ DatagramSocket socket = null; BufferedReader sysIn = null; private int MyPort; private String ToIP; private int ToPort; public UdpTalkSend(int myPort, String toIP, int toPort) { this.MyPort = myPort; this.ToIP = toIP; this.ToPort = toPort; try { socket = new DatagramSocket(MyPort); } catch (SocketException e) { throw new RuntimeException(e); } } @Override public void run() { } }
- 搭建接收的线程
重写run方法
@Override public void run() { int count=10; while (count>0){ try { //准备接收数据包 byte[] bytes = new byte[1024]; packet = new DatagramPacket(bytes, 0, bytes.length); socket.receive(packet); String data = new String(packet.getData(), 0, packet.getLength()); System.out.println(username+":"+data); count--; if (data.equals("bye")){ break; } } catch (IOException e) { throw new RuntimeException(e); } } //关闭流 socket.close(); }
构造方法
public class UdpTalkReceive implements Runnable { DatagramSocket socket = null; DatagramPacket packet = null; private int ToPort; private String username; public UdpTalkReceive(int toPort, String username) { ToPort = toPort; this.username = username; try { socket = new DatagramSocket(ToPort); } catch (SocketException e) { throw new RuntimeException(e); } } @Override public void run() { } }
模拟两个用户A和B
A:
public class UserClientA { public static void main(String[] args) { new Thread(new UdpTalkReceive(5202,"B")).start(); new Thread(new UdpTalkSend(5203,"127.0.0.1",5201)).start(); } }
B:
public class UserClientB { public static void main(String[] args) { new Thread(new UdpTalkReceive(5201,"A")).start(); new Thread(new UdpTalkSend(5204,"localhost",5202)).start(); } }
测试结果:
四.使用java.net.URL类下载
我使用的是在网易云上下载了一首音乐下来
获取下载路径:
//得到url路径资源 URL url = new URL("https://m801.music.126.net/20231129230405/aabdfb2ffd40439ec5c68a80c11a0140/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/14096410414/5dd8/3527/d0a8/2bc39cc62c984590b57fff0024c23780.m4a");
和URL地址创建连接
//创建连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
下载也是IO流,所以创建一个流
//创建写入流 InputStream io = connection.getInputStream(); FileOutputStream file = new FileOutputStream(new File("世界美好.m4a"));
利用IO流将.m4a文件写入到本地
//开始写入 byte[] buffer = new byte[1024]; int len; while ((len=io.read(buffer))!=-1){ file.write(buffer,0,len); //写出数据 }
断开连接
//断开连接 file.close(); io.close(); connection.disconnect();
最后在本地会得到一个.m4a文件
标签:Java,socket,--,packet,buffer,close,new,Lesson,byte From: https://www.cnblogs.com/5ran2yl/p/17860743.html