网络编程

网络通信

  • 概念:两台设备之间通过网络实现数据传输。
  • java.net包下通过了一系列的类或者接口,供程序员使用,完成网络通信

网络分类(覆盖范围)

  • 局域网:覆盖范围最小,仅仅是一个教室或一个机房。
  • 城域网:覆盖范围较大,可以覆盖一个城市。
  • 广域网:覆盖范围最大,可以覆盖全国,甚至全球,万维网是广域网的代表。

IP地址

概念:用于唯一标识网络中的每台计算机/主机

组成:网络地址+主机地址 如:192.168.16.69.

 协议

TCP和UDP的区别

InetAddress类 

// 获取本机的InetAddress 对象
InetAddress localhost = InetAddress.getLocalHost();
System.out.println(localhost);// 计算机名/ip地址

// 根据指定的主机名获取对象
InetAddress host = InetAddress.getByName("DESKTOP-49H260O");
System.out.println(host);

// 根据域名返回 InetAddress对象
InetAddress host2 = InetAddress.getByName("www.baidu.com");
System.out.println(host2);

// 通过 InetAddress对象,获取对应的地址
String host2HostAddress = host2.getHostAddress();
System.out.println(host2HostAddress);// IP地址

// 通过 InetAddress对象,获取对应的主机名/域名
String hostName = host2.getHostName();
System.out.println(hostName);

Socket(TCP编程和UDP编程)

 图示

 TCP编程

// 服务端 : 上传图片
//
1. 服务端在本机监听8888端口 ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务端在8888端口监听...."); //2. 等待连接 Socket socket = serverSocket.accept(); //3. 读取客户端发送的数据 // 通过Socket得到输入流 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); byte[] bytes = StreamUtils.streamToByteArray(bis); //4. 将得到 bytes 数组,写入到指定的路径,就得到一个文件了 String destFilePath = "src\\abc.mp4"; BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath)); bos.write(bytes); bos.close(); // 向客户端回复 "收到图片" // 通过socket 获取到输出流(字符) BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); writer.write("收到图片"); writer.flush();//把内容刷新到数据通道 socket.shutdownOutput();//设置写入结束标记 //关闭其他资源 writer.close(); bis.close(); socket.close(); serverSocket.close();
// 客户端
//客户端连接服务端 8888,得到Socket对象
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
//创建读取磁盘文件的输入流
//String filePath = "e:\\qie.png";
String filePath = "e:\\abc.mp4";
BufferedInputStream bis  = new BufferedInputStream(new FileInputStream(filePath));

//bytes 就是filePath对应的字节数组
byte[] bytes = StreamUtils.streamToByteArray(bis);

//通过socket获取到输出流, 将bytes数据发送给服务端
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write(bytes);//将文件对应的字节数组的内容,写入到数据通道
bis.close();
socket.shutdownOutput();//设置写入数据的结束标记

//=====接收从服务端回复的消息=====

InputStream inputStream = socket.getInputStream();
//使用StreamUtils 的方法,直接将 inputStream 读取到的内容 转成字符串
String s = StreamUtils.streamToString(inputStream);
System.out.println(s);


//关闭相关的流
inputStream.close();
bos.close();
socket.close();
// StreamUtils类
/**
 * 功能:将输入流转换成byte[]
 * @param is
 * @return
 * @throws Exception
 */
public static byte[] streamToByteArray(InputStream is) throws Exception{
    ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象
    byte[] b = new byte[1024];
    int len;
    while((len=is.read(b))!=-1){
        bos.write(b, 0, len);
    }
    byte[] array = bos.toByteArray();
    bos.close();
    return array;
}
/**
 * 功能:将InputStream转换成String
 * @param is
 * @return
 * @throws Exception
 */

public static String streamToString(InputStream is) throws Exception{
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder builder= new StringBuilder();
    String line;
    while((line=reader.readLine())!=null){ //当读取到 null时,就表示结束
        builder.append(line+"\r\n");
    }
    return builder.toString();

}
StreamUtils类

注意:当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是TCP/IP分配的。

 UDP编程

代码

//1.创建 DatagramSocket 对象,准备在9998端口 接收数据
DatagramSocket socket = new DatagramSocket(9998);

//2. 将需要发送的数据,封装到 DatagramPacket对象
byte[] data = "hello 明天吃火锅~".getBytes(); //

//说明: 封装的 DatagramPacket对象 data 内容字节数组 , data.length , 主机(IP) , 端口
DatagramPacket packet =
        new DatagramPacket(data, data.length, InetAddress.getByName("192.168.12.1"), 9999);

socket.send(packet);

//3.=== 接收从A端回复的信息
//(1)   构建一个 DatagramPacket 对象,准备接收数据
//  一个数据包最大 64k
byte[] buf = new byte[1024];
packet = new DatagramPacket(buf, buf.length);
//(2)    调用 接收方法, 将通过网络传输的 DatagramPacket 对象
//   填充到 packet对象
//提示: 当有数据包发送到 本机的9998端口时,就会接收到数据
//   如果没有数据包发送到 本机的9998端口, 就会阻塞等待.
socket.receive(packet);

//(3)  可以把packet 进行拆包,取出数据,并显示.
int length = packet.getLength();//实际接收到的数据字节长度
data = packet.getData();//接收到数据
String s = new String(data, 0, length);
System.out.println(s);

//关闭资源
socket.close();
System.out.println("B端退出");
UDP接收端
//1. 创建一个 DatagramSocket 对象,准备在9999接收数据
DatagramSocket socket = new DatagramSocket(9999);
//2. 构建一个 DatagramPacket 对象,准备接收数据
//   在前面讲解UDP 协议时,老师说过一个数据包最大 64k
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
//3. 调用 接收方法, 将通过网络传输的 DatagramPacket 对象
//   填充到 packet对象
//   提示: 当有数据包发送到 本机的9999端口时,就会接收到数据
//   如果没有数据包发送到 本机的9999端口, 就会阻塞等待.
System.out.println("接收端A 等待接收数据..");
socket.receive(packet);

//4. 可以把packet 进行拆包,取出数据,并显示.
int length = packet.getLength();//实际接收到的数据字节长度
byte[] data = packet.getData();//接收到数据
String s = new String(data, 0, length);
System.out.println(s);


//===回复信息给B端
//将需要发送的数据,封装到 DatagramPacket对象
data = "好的, 明天见".getBytes();
//说明: 封装的 DatagramPacket对象 data 内容字节数组 , data.length , 主机(IP) , 端口
packet =
        new DatagramPacket(data, data.length, InetAddress.getByName("192.168.12.1"), 9998);

socket.send(packet);//发送

//5. 关闭资源
socket.close();
System.out.println("A端退出...");
UDP接收端

 

posted @ 2023-06-24 01:59  颜欢兮  阅读(20)  评论(0)    收藏  举报