java复习笔记--网络编程

学了java这么久了,还是老是忘记,所以这次又重新整理一遍笔记,希望对大家也有帮助


在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换

网络编程三要素

IP地址

IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异
要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,通过这个标识号来指定要接收数
据的计算机和识别发送的计算机,而IP地址就是这个标识号。也就是设备的标识

ip地址的分类

每一个IP地址包括两部分:网络地址和主机地址。IP地址通常由点分十进制(例如:192.168.1.1)的方式来表示,IP地址要和子网掩码(用来区分网络位和主机位)配合使用。
在这里插入图片描述
注意事项:


每一个字节都为0的地址(“0.0.0.0”)对应于当前主机。
IP地址中的每一个字节都为1的IP地址(“255255255255”)
是当前子网的广播地址。
IP地址中凡是以“1111”开头的E类IP地址都保留用于将来和实验使用。
IP地址中不能以十进制“127”作为开头,该类地址中数字127001127255255255用于回路测试,如:127.0.0.1可以代表本机IP地址,
用 http://127.0.0.1 就可以测试本机中配置的Web服务器网络ID的第一
个8位组也不能全置为“0”,全“0”表示本地网络

DOS常用命令:
ipconfig:查看本机IP地址
ping IP地址:检查网络是否连通

特殊IP地址:
127.0.0.1:是回送地址,可以代表本机地址,一般用来测试使用

端口

端口号

端口是通过端口号来标记的,端口号只有整数,范围是从0到65535.端口号不是随意使用的,而是按照一定的规定进行分配

知名端口号

知名端口是众所周知的端口号,范围从0到1023,以理解为,一些常用的功能使用的号码是估计的,好比 电话号码110、10086、10010一样。一般情况下,如果一个程序需要使用知名端口的需要有root权限。

动态端口号

动态端口的范围是从1024到65535

之所以称为动态端口,是因为它一般不固定分配某种服务,而是动态分配。

动态分配是指当一个系统程序或应用程序程序需要网络通信时,它向主机申请一个端口,主机从可用的端口号中分配一个供它使用。

当这个程序关闭时,同时也就释放了所占用的端口号

常用端口:

mysql:3306
sqlserver:1433
oracle:1521
tomcat:8080
浏览器:80

协议

通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定
的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样。在计算机网络中,这些连接和通信的规则
被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守
才能完成数据交换。常见的协议有UDP协议和TCP协议

InetAddress类

InetAddress:此类表示Internet协议(IP)地址
相关方法

方法名 说明
static InetAddress getByName(Stringhost) 确定主机名称的IP地址。主机名称可以是器名称,也可以是IP地址
String getHostName() 获取此IP地址的主机名
String getHostAddress() 返回文本显示中的IP地址字符串
import java.net.InetAddress;
import java.net.UnknownHostException;

public class l1 {
    
    
    public static void main(String[] args) throws UnknownHostException {
    
    
       InetAddress address = InetAddress.getByName("192.168.11.103");
        //public String getHostAddress():返回文本显示中的IP地址字符串
         String hostAddress = address.getHostAddress(); //192.168.11.103
        //public String getHostName():获取此IP地址的主机名
         String hostName = address.getHostName(); //DESKTOP-J91LIML

        System.out.println(hostAddress+"   "+hostName);
    }
}

UDP协议

用户数据报协议(User Datagram Protocol)
UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。

由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输

例如视频会议通常采用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议

UDP通信程序

Java中的UDP通信
UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象,因此对于基于UDP协议的通信双方而言,没有所谓的客户端和服务器的概念

Java提供了DatagramSocket类作为基于UDP协议的Socket

构造方法

方法名 说明
DatagramSocket() 创建数据报套接字并将其绑定到本机地址上的任何可用端口
DatagramSocket​(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口
DatagramPacket(byte[] buf,int len,InetAddressadd,int port) 创建数据包,发送长度为le的数据包到指定主机的指定端口
DatagramPacket(byte[] buf, int len) 创建一个DatagramPacket用于接收长度为len的数据包

相关方法

方法名 说明
void send(DatagramPacket p) 发送数据报包
void close() 关闭数据报套接字
void receive(DatagramPacket p) 从此套接字接受数据报包

发送数据的步骤

创建发送端的Socket对象(DatagramSocket)
创建数据,并把数据打包
调用DatagramSocket对象的方法发送数据
关闭发送端

udp发送数据

import java.io.IOException;
import java.net.*;

public class udp {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口
         DatagramSocket ds = new DatagramSocket();
         byte[] bytes = "dyk666".getBytes();
        //创建数据,并把数据打包
        //DatagramPacket(byte[] buf, int length, InetAddress address, int port)
        //构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。

        DatagramPacket dp=new DatagramPacket(bytes,bytes.length, InetAddress.getByName("127.0.0.1"),10086);

        //调用DatagramSocket对象的方法发送数据
        ds.send(dp);
        //关闭发送端
        ds.close();
    }
}

udp接收数据

接收数据的步骤

创建接收端的Socket对象(DatagramSocket)
创建一个数据包,用于接收数据
调用DatagramSocket对象的方法接收数据
解析数据包,并把数据在控制台显示
关闭接收端

解析数据包的方法

方法名 说明
byte[] getData() 返回数据缓冲区
int getLength() 返回要发送的数据的长度或接收的数据的长度
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class udpr {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //创建接收端的Socket对象(DatagramSocket)
        DatagramSocket ds=new DatagramSocket(10086);
        while (true)
        {
    
    
            //创建一个数据包,用于接收数据

            byte[] bys=new byte[1024];
            DatagramPacket dp=new DatagramPacket(bys,bys.length);
            ds.receive(dp);
            System.out.println("接收到的数据是:"+new String(dp.getData(),0,dp.getLength()));

        }

    }
}

TCP通信程序

TCP(Transmission Control Protocol)传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议

Java中的TCP通信

Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过
Socket产生IO流来进行网络通信。
Java为客户端提供了Socket类,为服务器端提供了ServerSocket类

构造方法

方法名 说明
Socket(InetAddress address,int port) 创建流套接字并将其连接到指定IP指定端口号
Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号
方法名 说明
ServletSocket(int port) 创建绑定到指定端口的服务器套接字

相关方法

方法名 说明
InputStream getInputStream() 返回此套接字的输入流
OutputStream getOutputStream() 返回此套接字的输出流
方法名 说明
Socket accept() 监听要连接到此的套接字并接受它

TCP发送数据


import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class tcps {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //创建客户端的Socket对象(Socket)

        Socket s=new Socket("127.0.0.1",10086);
        //获取输出流,写数据
       //OutputStream getOutputStream() 返回此套接字的输出流
         OutputStream outputStream = s.getOutputStream();
      byte[] bytes = "dyk666".getBytes();
        outputStream.write(bytes);
        s.close();
    }
}

TCP接收数据

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class tcpr {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //创建服务器端的Socket对象(ServerSocket)
//ServerSocket(int port) 创建绑定到指定端口的服务器套接字
        ServerSocket ss=new ServerSocket(10086);
        //Socket accept() 侦听要连接到此套接字并接受它
        Socket s = ss.accept();
        //获取输入流,读数据,并把数据显示在控制台
         InputStream is = s.getInputStream();
         byte[] bys=new byte[1024];
         int len;
         while((len=is.read(bys))!=-1){
    
    
             String data=new String(bys,0,len);
             System.out.println(data);
         }
         ss.close();
         s.close();
    }
}

注意,在运行tcp程序时,一定要先运行服务器,后运行客户端,不然会报错误 java.net.ConnectException: Connection refused: connect

tcp上传文件

客户端:数据来自于文本文件,接收服务器反馈
服务器:接收到的数据写入文本文件,给出反馈

由于读数据的方法是阻塞式的,服务器读数据的时候如果读不到数据会出现一直等待的现象,而导致程序卡死在哪

所以socket提供了方法来作为结束的标记,当读到此标记时会自动结束

方法名 说明
void shutdownInput() 将此套接字的输入流放置在“流的末尾”
void shutdownOutput() 禁止用此套接字的输出流

客户端


import java.io.*;
import java.net.Socket;

public class tcps {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //创建客户端的Socket对象(Socket)

        Socket s=new Socket("127.0.0.1",10086);
        //封装文本文件的数据
        BufferedReader br=new BufferedReader(new FileReader("D:\\iotest\\dyk3.txt"));
        //封装输出流写数据
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
       String line;
       while((line=br.readLine())!=null)
       {
    
    
           bw.write(line);
           bw.newLine();
           bw.flush();
       }

        //public void shutdownOutput()
        s.shutdownOutput();

        //接收反馈
       BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(s.getInputStream()));
            String data=bufferedReader.readLine();
        System.out.println("服务器说: "+data);


        bufferedReader.close();
        br.close();
       bw.close();
        s.close();
    }
}

服务器

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class tcpr {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //创建服务器端的Socket对象(ServerSocket)
//ServerSocket(int port) 创建绑定到指定端口的服务器套接字
        ServerSocket ss=new ServerSocket(10086);
        //Socket accept() 侦听要连接到此套接字并接受它
        Socket s = ss.accept();
        //接收数据

        BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter bw=new BufferedWriter(new FileWriter("123.txt"));
        String line;
        while ((line=br.readLine())!=null)
        {
    
    
            bw.write(line);
            bw.newLine();
            bw.flush();
        }
        BufferedWriter bufferedWriter=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        bufferedWriter.write("文件上传成功");
        bufferedWriter.newLine();
        bufferedWriter.flush();

        ss.close();
        bw.close();

    }
}

猜你喜欢

转载自blog.csdn.net/qq_44866153/article/details/113003418