网络编程

Posted Spring-_-Bear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程相关的知识,希望对你有一定的参考价值。

第21章 网络编程

662. 网络相关概念

663. IP地址

  • IP 地址概念: 用于唯一标识网络中的每台计算机(主机)
  • DOS 查看 IP 地址:ipconfig
  • IPV4 用 4 字节共 32 位标识一个 IP 地址(点分十进制)
  • IPV6 用 8 字节共 128 位标识一个 IP 地址
  • IP 地址的组成:网络地址 + 主机地址
  • IPV4 的分类:127.0.0.1 表示本机地址
分类表示方法范围
A0 + 7 位网络号 + 24 位主机号0.0.0.0 ~ 127.255.255.255
B10 + 14 位网络号 + 16 位主机号128.0.0.0 ~ 191.255.255.255
C110 + 21 位网络号 + 8 位主机号192.0.0.0 ~ 223.255.255.255
D1110 + 28 位多播组号224.0.0.0 ~ 239.255.255.255
E11110 + 27 位留待后用240.0.0.0 ~ 247.255.255.255

664. 域名和端口

  • 域名:将 IP 地址映射成域名(http 协议)
  • 端口:用于标识计算机上特定的网络程序,以整数形式表示,范围是 0 ~ 65535,其中 0 ~ 1024 已被占用。常见的网络程序端口:ssh 22;ftp 21;smtp 25;http 80;tomcat 8080;mysql 3306;oracle 1521;sql server 1433

665. 网络协议

  • TCP / IP(Transmission Control Protocol / Internet Protocol):传输控制协议 / 因特网互联协议,又名网络通讯协议

TCP/IP模型对应协议
应用层http、ftp、telnet、DNS···
传输层TCP、UDP···
网络层IP、ICMP、ARP···
物理 + 数据链路层Link

666. TCP和UDP

  • TCP(Transmission Control Protocol):在使用 TCP 协议前,须先建立 TCP 连接,形成传输数据通道;传输前,采用 ”三次握手“ 方式建立连接,传输可靠;TCP 协议进行通信的两个应用程序:客户端、服务端;在连接中可进行大量数据的传输;传输完毕,需释放已建立的连接,效率较低
  • UDP(User Data Protocol):将数据、源、目的封装成数据包,不需要建立连接,传输不可靠,无需释放资源,速度快;每个数据包的大小限制在 64K 以内

667. InetAddress

方法名功能
getLocalHost获取本机 InetAddress 对象
getByName根据指定主机名 / 域名获取 InetAddress 对象
getHostName获取 InetAddress 对象的主机名
getHostAddress获取 InetAddress 对象的 ip 地址
// 获取本机的 InetAddress 对象
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);

// 根据指定主机名/域名获取 InetAddress 对象
InetAddress csdn = InetAddress.getByName("www.csdn.net");
System.out.println(csdn);
InetAddress springBear = InetAddress.getByName("SpringBear");
System.out.println(springBear);

// 获取 InetAddress 对象的主机名
System.out.println(localHost.getHostName());
System.out.println(csdn.getHostName());
// 获取 InetAddress 对象的 ip 地址
System.out.println(springBear.getHostAddress());
System.out.println(csdn.getHostAddress());

668. Socket

  • Socket(套接字)开发网络应用程序时被广泛使用,以至于成为事实上的标准;通信的两端都要有 Socket,是两台机器间通信的端点;网络通信其实就是 Socket 间的通信;Socket 允许程序把网络连接当作是一个流,数据在两个 Socket 间通过 IO 传输;一般发起通信的应用程序属客户端,等待通信请求的为服务端

669. TCP字节流编程1

  • Server
// 监听端口
ServerSocket serverSocket = new ServerSocket(4444);
// 等待连接
Socket socket = serverSocket.accept();

// 从数据通道中读取数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen;
while ((readLen = inputStream.read(buf)) != -1) 
   System.out.println(new String(buf, 0, readLen));


// 关闭资源
inputStream.close();
socket.close();
serverSocket.close();
  • Client
// 建立连接
Socket socket = new Socket(InetAddress.getLocalHost(), 4444);

// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello,Server!".getBytes(StandardCharsets.UTF_8));

// 关闭资源
outputStream.close();
socket.close();

670. TCP字节流编程2

  • Server
// 监听端口
ServerSocket serverSocket = new ServerSocket(5555);
// 等待连接
Socket socket = serverSocket.accept();

// 从数据通道读取数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen;
while ((readLen = inputStream.read(buf)) != -1) 
   System.out.println(new String(buf, 0, readLen));

// 关闭 socket 的输入流
socket.shutdownInput();

// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello,Client!".getBytes(StandardCharsets.UTF_8));

// 关闭资源
outputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
  • Client
// 建立连接
Socket socket = new Socket(InetAddress.getLocalHost(), 5555);

// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello,Server!".getBytes(StandardCharsets.UTF_8));
// 关闭 socket 的输出流
socket.shutdownOutput();

// 从数据通道读取数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen;
while ((readLen = inputStream.read(buf)) != -1) 
   System.out.println(new String(buf, 0, readLen));


// 关闭资源
inputStream.close();
outputStream.close();
socket.close();

671. TCP字符流编程

  • Server
// 监听端口
ServerSocket serverSocket = new ServerSocket(6666);
// 等待连接
Socket socket = serverSocket.accept();

// 从数据通道读取信息
InputStream inputStream = socket.getInputStream();
// 字节输入流转换成字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
System.out.println(bufferedReader.readLine());

// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
// 字节输出流转换成字符输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("Hello,Client!");
// 行分隔符,写入结束标志
bufferedWriter.newLine();
// 刷新缓冲区,写入数据通道
bufferedWriter.flush();

// 关闭资源
bufferedWriter.close();
bufferedReader.close();
socket.close();
serverSocket.close();
  • Client
// 建立连接
Socket socket = new Socket(InetAddress.getLocalHost(), 6666);

// 写入数据到数据通道
OutputStream outputStream = socket.getOutputStream();
// 字符输出流转换从字节输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("Hello,Server!");
// 行分隔符,写入结束标记
bufferedWriter.newLine();
// 刷新缓冲区,写入数据通道
bufferedWriter.flush();

// 从数据通道读取数据
InputStream inputStream = socket.getInputStream();
// 字节输入流转换成字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
System.out.println(bufferedReader.readLine());

// 关闭资源
bufferedReader.close();
bufferedWriter.close();
socket.close();

672. 网络上传文件1

673. 网络上传文件2

674. 网络上传文件3

  • Server
File saveFilePath = new File("C:\\\\Users\\\\Admin\\\\Desktop\\\\temp.jpg");

// 从数据通道中读取源文件字节数组
ServerSocket serverSocket = new ServerSocket(5555);
Socket socket = serverSocket.accept();
InputStream socketInputStream = socket.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int readLen;
byte[] buf = new byte[1024];
while ((readLen = socketInputStream.read(buf)) != -1) 
   byteArrayOutputStream.write(buf, 0, readLen);

buf = byteArrayOutputStream.toByteArray();
socket.shutdownInput();

// 将接收到的字节数组写入磁盘
FileOutputStream fileOutputStream = new FileOutputStream(saveFilePath);
fileOutputStream.write(buf);

// 向客户端反馈消息
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write("Receive file successfully!".getBytes(StandardCharsets.UTF_8));
socket.shutdownOutput();

socketOutputStream.close();
fileOutputStream.close();
byteArrayOutputStream.close();
socketInputStream.close();
socket.close();
serverSocket.close();
  • Client
File sourceFilePath = new File("C:\\\\Users\\\\Admin\\\\Desktop\\\\fishing.jpg");

// 从磁盘中读取源文件存入字节数组
int readLen;
byte[] buf = new byte[1024];
FileInputStream fileInputStream = new FileInputStream(sourceFilePath);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while ((readLen = fileInputStream.read(buf)) != -1) 
   byteArrayOutputStream.write(buf, 0, readLen);

buf = byteArrayOutputStream.toByteArray();

// 发送源文件字节数组到数据通道
Socket socket = new Socket(InetAddress.getLocalHost(), 5555);
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write(buf);
socket.shutdownOutput();

// 从数据通道读取服务器反馈的消息
InputStream socketInputStream = socket.getInputStream();
while ((readLen = socketInputStream.read(buf)) != -1) 
   System.out.println(new String(buf, 0, readLen));


socketInputStream.close();
socketOutputStream.close();
socket.close();
byteArrayOutputStream.close();
fileInputStream.close();

675. netstat

  • netstat -an:可以查看当前主机网络情况,包括端口监听和网络连接情况:

  • netstat -anb:管理员身份运行可以查看监听端口的程序

  • 命令后跟参数 | more 可以进行分页显示;ctrl + c(double) 可以退出查看

676. TCP链接秘密

  • 当客户端与服务端建立连接后,实际上客户端也是通过一个端口与服务端进行通信的,这个端口号是根据 TCP / IP 由系统随机分配的
ProtoLocal AddressForeign AddressState
TCP10.138.141.42:555510.138.141.42:52820ESTABLISHED

677. UDP原理

  • UDP 编程没有明确的服务端和客户端,因此无需建立连接
  • UDP 数据包通过数据包套接字 DatagramSocket 实现发送和接收,系统不保证 UDP 数据包一定送达目的地,也不确定什么时候可以送达
  • DatagramSocket 对象封装了 UDP 数据包,在数据包中封装了数据、发送端和接收端的 IP 地址以及端口信息

678. UDP网络编程1

679. UDP网络编程2

  • Receiver
// 监听端口
DatagramSocket socket = new DatagramSocket(7777);

// 接收包
// 用户保存数据包的缓冲区
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// 拆包,获取数据
int dataLen = packet.getLength();
byte[] data = packet.getData();
System.out.println(new String(data, 0, dataLen));

// 装包,封装数据
buf = "Hello, sender!".getBytes(StandardCharsets.UTF_8);
packet = new DatagramPacket(buf, 0, buf.length, InetAddress.getLocalHost(), 8888);
// 发送包
socket.send(packet);

// 关闭资源
socket.close();
  • Sender
// 监听端口
DatagramSocket socket = new DatagramSocket(8888);

// 装包,封装数据
byte[] data = "Hello, receiver!".getBytes(StandardCharsets.UTF_8);
DatagramPacket packet = new DatagramPacket(data, 0, data.length, InetAddress.getLocalHost(), 7777);
// 发送包
socket.send(packet);

// 接收包
// 用于保存数据包的缓冲区
byte[] buf = new byte[1024];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
// 拆包,获取数据
int dataLen = packet.getLength();
data = packet.getData();
System.out.println(new String(data, 0, dataLen));

// 关闭资源
socket.close();

680. 网络编程作业1

681. 网络编程作业2

682. TCP文件下载1

683. TCP文件下载2

684. 网络编程梳理

以上是关于网络编程的主要内容,如果未能解决你的问题,请参考以下文章

unix网络编程 需要买几卷

javaAPI_网络编程基础_网络编程基础1

QT 网络编程问题

读过 Unix网络编程 或者 熟知Unix网络编程的 的进来看一下

Java网络编程中怎样用管道流

求unix网络编程