网络

网络的概念和分类:

网络就是连接在一起共享数据和资源的一组计算机
计算机网络指实现网络通信
按照地理覆盖范围网络可分为局域网,城域网,广域网
局域网(LAN):局限在小的地理区域内或单独的建筑物内
城域网(MAN):覆盖城市或城镇内的广大地理区域
广域网(WAN):实在一个更大的范围内所建立的计算机通信网络,其范围可以超越城市和国家以致全球

网络分层模型:

国际标准化组织(ISO)于1984年颁布了开放系统互连参考模型(OSI)
OSI将网络分为7层:

分层 功能
应用层 网络服务和最终用户的接口
表示层 数据的表示,安全和压缩
会话层 建立,管理和终止会话
传输层 定义传输数据斜阳的端口号,流量控制和差错恢恢复
网络层 进行逻辑地址寻址,实现不同的网络之间的路径选择
数据链路层 建立逻辑链接,进行硬件地址寻址,差错检验等功能
物理层 建立,维护,断开物理连接

OSI模型与TCP/IP模型对比:
image.png

IP地址

IP地址概述

在网络中使用一种具有层次结构的逻辑地址来表示一台主机,这个地址称为IP地址
IP地址目前存在IPV4和IPV6两种标准

IP地址的组成和分类

IP地址的组成

IPV4有32位,由4个8位2进制数组成,每8位之间用圆点隔开,由于2进制不方便记忆所以通常将2进制装换为十进制数来表示,一个IP地址通常有3个点号分开的4个十进制数表示,称为点分十进制
IPV6地址有128位,有8个16位的无符号整数组成,每个整数用4个十六进制数表示,这些数之间用冒号(:)分开。

IP地址的分类

IP地址包含网络地址和主机地址两部分,其中网络地址决定了可以分配的最大网络数,主机地址决定了一个网络中可以存在的最大的计算机的数量
IP地址的网络地址由互联网数字分配机构(IANA)统一分配,IANA将IP地址分为A,B,C,D,E五类,并规定每个类的网络地址和主机地址的长度
image.png
A类IP地址:第一组数字表示网络地址,其余三位表示主机地址,A类地址的第一位有效取值范围为1~126
B类IP地址:第两组数字表示网络地址,其余两位表示主机地址,B类地址的第一位有效取值范围为128~191
C类IP地址:第三组数字表示网络地址,其余一位表示主机地址,C类地址的第一位有效取值范围为192~223
D类IP地址:不分网络地址和主机地址,用于组播通信不能在互联网上作为节点地址使用,D类地址的第一位有效取值范围为224~239
D类IP地址:不分网络地址和主机地址,用于科学研究不能在互联网上作为节点地址使用,D类地址的第一位有效取值范围为240~254
特殊IP地址:
0.0.0.0:表示本机
127.0.0.1:表示本机回环地址
255.255.255.255:表示当前子网,一般用于向当前子网广播消息

ServerSocket类

等待客户端建立链接,建立以后进行通信

ServerSocket构造方法:

1.接收端口号作为参数创建serversocket对象:ServerSocket s=new ServerSocket(port);
2.接收端口号和最大对列长度作为参数,最大链接长度表示系统在拒绝连接前可以拥有客户端的最大连接数:ServerSocket s=new ServerSocket(port,maxqu);

常用方法:

方法 说明
Socket accept() 侦听对此套接字的连接并接受它
InetAddress getInetAddress() 返回套接字的本地地址

Socket类

Socket对象在客户端和服务器之间建立链接,可用Socket类的构造方法创建套接字,并将此套接字连接至指定的主机和端口。

Socket构造方法:

1.构造方法以主机名和端口号作为来创建一个Socket对象:Socket socket=new Socket(hostName,port);
2.以InetAddress对象和端口号作为参数来创一个Socket对象:Socket socket=new Socket(address,port);

常用方法:

方法 说明
InetAddress getInetAddress() 返回与socket对象关联的inetaddress(地址)
int getport() 返回此socket对象所连接的远程端口
int getLocalPort() 返回此socket对象所连接的本地端口
InputStream getInputStream() 返回与此套接字关联的InputStream
OutputStream getOutputStream() 返回与此套接字关联的OutputStream
void ShutdownInput() 将此套接字的输入流放在“流结束”
void ShutdownOutput() 禁用此套接字的输出流

服务器示例:

  1. public class TcpSerer {
  2. public static void main(String[] args) {
  3. String s="响应";
  4. try {
  5. //构建serversocket对象
  6. ServerSocket serverSocket=new ServerSocket(8888);
  7. System.out.println("服务器已启动,监听中.......");
  8. //阻塞服务器,等待客户端端发送数据
  9. Socket socket=serverSocket.accept();
  10. //构建输入流接收客户端发送的数据
  11. InputStream is=socket.getInputStream();
  12. byte[] bytes=new byte[1024];
  13. int len;
  14. while ((len=is.read(bytes))!=-1){
  15. //打印
  16. System.out.println("客户端:"+new String(bytes,0,len));
  17. }
  18. //响应客户端
  19. OutputStream os=socket.getOutputStream();
  20. os.write(s.getBytes());
  21. os.close();
  22. is.close();
  23. socket.close();
  24. serverSocket.close();
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }

客户端示例:

  1. public class TcpClient {
  2. public static void main(String[] args) {
  3. try {
  4. //创建socket对象用于向客户端发送消息
  5. Socket socket=new Socket("127.0.0.1",8888);
  6. //构建输出流
  7. OutputStream os=socket.getOutputStream();
  8. //向服务器发送数据
  9. os.write("你好服务器".getBytes());
  10. //禁用套接字的输出流
  11. socket.shutdownOutput();
  12. //构建输入流接收服务器的响应消息
  13. InputStream is =socket.getInputStream();
  14. byte[] bytes=new byte[1024];
  15. int len;
  16. while ((len=is.read(bytes))!=-1){
  17. System.out.println("客户端响应信息为:\n"+new String(bytes,0,len));
  18. }
  19. is.close();
  20. os.close();
  21. socket.close();
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. }
  25. }
  26. }

传输对象服务端示例:

  1. public class userServer {
  2. public static void main(String[] args) {
  3. try {
  4. ServerSocket serverSocket = new ServerSocket(8848);
  5. System.out.println("服务器已启动...");
  6. Socket socket=serverSocket.accept();
  7. ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
  8. user user=(user) ois.readObject();
  9. System.out.println(socket.getInetAddress()+"客户端发送:姓名:"+user.getName()+",年龄:"+user.getAge());
  10. //响应客户端
  11. OutputStream os=socket.getOutputStream();
  12. os.write("成功接收!".getBytes());
  13. os.close();
  14. ois.close();
  15. serverSocket.close();
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. } catch (ClassNotFoundException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. }

传输对象客户端示例:

  1. public class userClient {
  2. public static void main(String[] args) {
  3. Scanner input=new Scanner(System.in);
  4. System.out.print("请输入姓名:");
  5. String name =input.next();
  6. System.out.print("请输入年龄:");
  7. String age =input.next();
  8. try {
  9. Socket socket=new Socket("127.0.0.1",8848);
  10. ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());
  11. oos.writeObject(new user(name,age));
  12. System.out.println("发送成功!");
  13. socket.shutdownOutput();
  14. InputStream is=socket.getInputStream();
  15. byte[] bytes=new byte[1024];
  16. int len;
  17. while ((len=is.read(bytes))!=-1){
  18. System.out.println("服务器:"+new String(bytes,0,len));
  19. }
  20. is.close();
  21. oos.close();
  22. socket.close();
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. }

多线程处理:

  1. public class userServer {
  2. public static void main(String[] args) {
  3. try {
  4. ServerSocket serverSocket = new ServerSocket(8848);
  5. System.out.println("服务器已启动...");
  6. while (true){
  7. Socket socket=serverSocket.accept();
  8. new userServer_server(socket).start();
  9. }
  10. } catch (IOException e) {
  11. e.printStackTrace();
  12. }
  13. }
  14. }
  1. public class Server_test extends Thread{
  2. Socket socket;
  3. public Server_test() {
  4. }
  5. public Server_test(Socket socket) {
  6. this.socket = socket;
  7. }
  8. @Override
  9. public void run() {
  10. Scanner input=new Scanner(System.in);
  11. try {
  12. InputStream is=socket.getInputStream();
  13. byte[] bytes=new byte[1024];
  14. int len;
  15. while ((len=is.read(bytes))!=-1){
  16. System.out.println("客户端:"+new String(bytes,0,len));
  17. }
  18. OutputStream os=socket.getOutputStream();
  19. System.out.print("回复:");
  20. String out=input.next();
  21. os.write(out.getBytes());
  22. socket.shutdownOutput();
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. }

image.png

TCP和UDP的区别:

1.Tcp面向链接Udp是无连接的,即发送数据之前不需要建立链接
2.TCP提供可靠的服务,也就是说通过TCP链接传送的数据,无差错,不丢失,不重复,且按序到达,upd尽最大努力交付
3.TCP面向字节流,实际上是TCP数据看成一连串无结构的节流,Udp是面向报文的,udp没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低
4.每一条TCP链接只能是点到点的,udp支持一对一,一对多,多对一和多对多的交互通信
5.TCP首部开销20字节,udp的内部开销小,只有8个字节
6.TCP的逻辑通信信道是全双工可靠信道,udp则是不可信信道

基于UDP协议的Socket编程

DatagramSocket类用于发送或接收,DatagramPacket类不提供发送或接收数据的方法,而DatagramSocket类提供的send()和receive()方法 用于通过套接字发送和接收数据

Datagrampacket类

构造方法:

方法 说明
DgramPacket(byte[] data,int size) 构建DatagramPacket对象,封装长度为size的数据包
DatagramPacket(byte[] buf,int length,InetAddress address,int port) 构建DatagramPacket对象并发送到指定主机,端口号

常用方法:

方法 说明
byte[] getData() 返回字节数组,该数组包含接收到或要发送的数据报中的数据
int getlength() 返回发送或接收的数据的长度
InetAddress getAddress () 返回接收或发送的数据报的主机的IP地址
int getport() 返接收或发送的此数据报的主机的端口号

DatagramSocket类

构造方法

方法 说明
DatagramSocket() 构建DatagramSocket对象,并将其与本地主机上的任何可用的端口绑定
DatagramSocket(int port) 创建DatagramSocket对象,并将其与本地主机上的指定端口绑定

常用方法

方法 说明
void connect(Inet Address address,int port) 将当前DatagramSocket对象链接到远程地址的指定地址
void close() 当前的DatagramSocket对象
void disconnect() 断开datagramsocket对象的链接
int getLocaPort() 返回当前DatagramSocket对象绑定的主机的端口号
void send(Datagrampacket p) 发送指定的数据报
void receive(Datagrampacket p) 接收数据报,收到以后存放在指定的Datagrampacket对象中

UDP协议客户端示例:

  1. public class UdpClient {
  2. public static void main(String[] args) {
  3. try {
  4. //创建链接对象
  5. DatagramSocket ds=new DatagramSocket();
  6. String msg="我是客户端!";
  7. //包装数据包
  8. DatagramPacket dp=new DatagramPacket(msg.getBytes(),msg.getBytes().length, InetAddress.getByName("192.168.0.167"),8888);
  9. //发
  10. ds.send(dp);
  11. //接收
  12. byte[] bytes=new byte[1024];
  13. dp=new DatagramPacket(bytes,bytes.length);
  14. ds.receive(dp);
  15. //解析数据,打印数据
  16. System.out.println(new String(dp.getData(),0,dp.getLength()));
  17. } catch (IOException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }

UDP协议服务器示例:

  1. public class UdpServer {
  2. public static void main(String[] args) {
  3. try {
  4. //构建Datagramsocket对象
  5. DatagramSocket ds=new DatagramSocket(8888);
  6. //创建空数据包
  7. byte[] bytes=new byte[1024];
  8. //包装数据包用于接收数据
  9. DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
  10. //接收
  11. ds.receive(dp);
  12. //解析数据,打印数据
  13. System.out.println(new String(dp.getData(),0,dp.getLength()));
  14. String msg="我是服务器!";
  15. //getSocketAddress()返回指定DatagramPacket对象的地址和端口
  16. DatagramPacket dp2=new DatagramPacket(msg.getBytes(),msg.getBytes().length,dp.getSocketAddress());
  17. //发送
  18. ds.send(dp2);
  19. System.out.println("发送成功");
  20. } catch (IOException e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. }