本文共 10614 字,大约阅读时间需要 35 分钟。
网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。
实现网络中的主机通信
1.通信双方的地址:IP、端口号
2.一定的规则:网络通信协议(OSI参考模型、TCP、IP协议)
IP地址:对应InetAddress类,一个对象代表一个IP地址;
IP地址分类
IPV4:4个字节组成
IPV6:16个字节,写成8个整数,每个整数用4位十六进制数表示,数之间用冒号隔开(X:X:X:X:X:X:X:X,X=_ _ _ _)
也可以分为
公网地址:万维网使用
私有地址:局域网使用,192.168开头,范围是0.0——255.255
InetAddress类,一个对象代表一个IP地址;
InetAddress inetAddress=InetAddress.getByName("127.0.0.1");getByName(String host)//InetAddress类中的静态方法,获得IP地址对象getLocalHost()//静态方法,获取本地IP地址//常用方法(非静态)getHostAddress()//获取本地地址getHostName()//获取本地域名
InetAddress常用方法
序号 | 方法描述 |
---|---|
1 | static InetAddress getByAddress(byte[] addr) 在给定原始 IP 地址的情况下,返回 InetAddress 对象。 |
2 | static InetAddress getByAddress(String host, byte[] addr) 根据提供的主机名和 IP 地址创建 InetAddress。 |
3 | static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。 |
4 | String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。 |
5 | String getHostName() 获取此 IP 地址的主机名。 |
6 | static InetAddress getLocalHost() 返回本地主机。 |
7 | String toString() 将此 IP 地址转换为 String。 |
域名
www.baidu.com
本地回路地址
127.0.0.1 对应localhost
端口号
端口分类
1.公认端口:0——1023,系统的保留端口,程序尽可能别使用这些端口;
2.注册端口:1024——49151
3.动态/私有端口:49152——65515
特定的端口号:MySQl 3306;Tomcat 8080
IP地址和端口号的组合得到一个网络套接字:Socket;
Socket(套接字)用来描述IP地址和端口,是通信链的句柄,应用程序可以通过Socket向网络发送请求或者应答网络请求;
Socket是支持TGP/IP协议的网络通信的基本操作单元,是对网络通信过程中端点的抽象表示,包含了进行网络通信所必须的五种信息:
1.连接所使用的协议;
2.本地主机的IP地址;
3.本地远程的协议端口;
4.远地主机的IP地址;
5.远地进程的协议端口;
public class ServerDemo extends Thread { //服务端 private ServerSocket serverSocket; public ServerDemo(int port) throws IOException{ serverSocket=new ServerSocket(port); serverSocket.setSoTimeout(10000); } @Override public void run() { while (true){ try { System.out.println("等待远程连接,端口号为:"+serverSocket.getLocalPort()); Socket server=serverSocket.accept(); System.out.println("远程主机地址:"+server.getRemoteSocketAddress()); DataInputStream dataInputStream=new DataInputStream(server.getInputStream()); System.out.println(dataInputStream.readUTF()); DataOutputStream dataOutputStream=new DataOutputStream(server.getOutputStream()); dataOutputStream.writeUTF("连接成功"+server.getLocalSocketAddress()+"\nGood bye"); server.close(); }catch (SocketTimeoutException e){ System.out.println("Socket Time Out"); break; }catch (IOException e){ e.printStackTrace(); break; } } } public static void main(String[] args) { int port=Integer.parseInt(args[0]); try{ Thread thread=new ServerDemo(port); thread.run(); }catch (IOException e){ e.printStackTrace(); } }}
public class ClientDemo { //客户端 public static void main(String[] args) { String serverName=args[0]; int port=Integer.parseInt(args[1]); try{ System.out.println("连接主机:"+serverName+",端口号:"+port); Socket client=new Socket(serverName,port); System.out.println("远程主机地址:"+client.getRemoteSocketAddress()); OutputStream outputStream=client.getOutputStream(); DataOutputStream dataOutputStream=new DataOutputStream(outputStream); dataOutputStream.writeUTF("Hello from"+client.getRemoteSocketAddress()); InputStream inputStream=client.getInputStream(); DataInputStream dataInputStream=new DataInputStream(inputStream); System.out.println("服务器响应"+dataInputStream.readUTF()); client.close(); }catch (IOException e){ e.printStackTrace(); } }}
服务器应用程序通过使用 java.net.ServerSocket 类以获取一个端口,并且侦听客户端请求。
ServerSocket 类有四个构造方法:
序号 | 方法描述 |
---|---|
1 | public ServerSocket(int port) throws IOException 创建绑定到特定端口的服务器套接字。 |
2 | public ServerSocket(int port, int backlog) throws IOException 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。 |
3 | public ServerSocket(int port, int backlog, InetAddress address) throws IOException 使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。 |
4 | public ServerSocket() throws IOException 创建非绑定服务器套接字。 |
ServerSocket 类的常用方法:
序号 | 方法描述 |
---|---|
1 | public int getLocalPort() 返回此套接字在其上侦听的端口。 |
2 | public Socket accept() throws IOException 侦听并接受到此套接字的连接。 |
3 | public void setSoTimeout(int timeout) 通过指定超时值启用/禁用 SO_TIMEOUT,以毫秒为单位。 |
4 | public void bind(SocketAddress host, int backlog) 将 ServerSocket 绑定到特定地址(IP 地址和端口号)。 |
java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket 对象通过实例化 ,而 服务器获得一个 Socket 对象通过 accept() 方法的返回值。
Socket 类有五个构造方法:
序号 | 方法描述 |
---|---|
1 | public Socket(String host, int port) throws UnknownHostException, IOException. 创建一个流套接字并将其连接到指定主机上的指定端口号。 |
2 | public Socket(InetAddress host, int port) throws IOException 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 |
3 | public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException. 创建一个套接字并将其连接到指定远程主机上的指定远程端口。 |
4 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException. 创建一个套接字并将其连接到指定远程地址上的指定远程端口。 |
5 | public Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字 |
Socket类常用方法
序号 | 方法描述 |
---|---|
1 | public void connect(SocketAddress host, int timeout) throws IOException 将此套接字连接到服务器,并指定一个超时值。 |
2 | public InetAddress getInetAddress() 返回套接字连接的地址。 |
3 | public int getPort() 返回此套接字连接到的远程端口。 |
4 | public int getLocalPort() 返回此套接字绑定到的本地端口。 |
5 | public SocketAddress getRemoteSocketAddress() 返回此套接字连接的端点的地址,如果未连接则返回 null。 |
6 | public InputStream getInputStream() throws IOException 返回此套接字的输入流。 |
7 | public OutputStream getOutputStream() throws IOException 返回此套接字的输出流。 |
8 | public void close() throws IOException 关闭此套接字。 |
1.创建ServerSocket和Socket;
2.打开连接到的Socket的输入/输出流;
3.按照协议对Socket进行读写操作;
4.关闭输入输出流以及Socket;
1.创建ServerSocket对象,绑定监听的端口;
2.调用accept()方法监听客户端的请求;
3.服务端与客户端连接建立以后,通过输入流读取客户端发送的请求信息;
4.通过输出流向客户端发送响应信息;
5.关闭相关资源;
public static void main(String[] args) throws IOException { //1.创建一个服务器端Socket,即ServerSocket,绑定指定的端口,并监听此端口; ServerSocket serverSocket=new ServerSocket(12345); InetAddress inetAddress=InetAddress.getLocalHost(); String ip=inetAddress.getHostAddress(); Socket socket=null; //2.调用accept()方法,等待客户端连接; System.out.println("服务端已就绪,等待客户端接入,服务端ip地址: " + ip); socket = serverSocket.accept(); //3.连接后获取输入流,读取客户端信息; InputStream inputStream=socket.getInputStream(); InputStreamReader inputStreamReader=new InputStreamReader(inputStream,"UTF-8"); BufferedReader bufferedReader=new BufferedReader(inputStreamReader); OutputStream outputStream=null; PrintWriter printWriter=null; String info=null; while((info=bufferedReader.readLine())!=null){ //循环读取客户端的信息 System.out.println("客户端发来信息"+info); socket.shutdownInput(); socket.close(); }
1.创建Socket对象,指明需要连接的服务器的地址和端口号;
2.连接建立以后,通过输出流向服务器发送请求信息;
3.通过输出流获取服务器响应的信息;
4.关闭相关资源;
Socket socket = new Socket("192.168.137.1",12345);//创建客户端Socket,指定服务器和端口OutputStream outputStream= socket.getOutputStream();//获取输出流,向客户端发送信息PrintWriter printWriter=new PrintWriter(outputStream);InetAddress inetAddress = InetAddress.getLocalHost();String ip=inetAddress.getHostAddress();//获取客户端的IP地址printWriter.write("客户端ip地址:"+ip+"接入服务器");printWriter.close();printWriter.flush();socket.shutdownOutput();//关闭输出流socket.close();
UDP通信无需建立发送和接收的连接,通过类DatagramSocket和DatagramPocket实现了基于UDP协议网络通信;
UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据是否一定能够安全地送到目的地,也不能确定什么时候可以送达;
1.创建DatagramSocket,指定端口号;
2.创建DatagramPacket;
3.接收客户端发送的数据信息;
4.读取数据;
public class UDPServer { public static void main(String[] args) throws IOException { /* * 接收客户端发送的数据 */ //1.创建服务端DatagramSocket,指定端口 DatagramSocket datagramSocket=new DatagramSocket(12345); //2.创建数据报,用于接收客户端发送的数据 byte[] data1=new byte[1024];//创建字节数组,指定接收的数据包的大小 DatagramPacket datagramPacket1=new DatagramPacket(data1,data1.length); //3.接受客户端发送的数据 System.out.println("服务端已经启动,等待客户端发送消息"); datagramSocket.receive(datagramPacket1);//此方法在接收到数据报之前会一直堵塞 //4.读取数据 String info=new String(data1,0,datagramPacket1.getLength()); System.out.println("客户端请求是:"+info); /* *响应给客户端的数据 */ //1.定义客户端的地址、端口号、数据 InetAddress inetAddress=datagramPacket1.getAddress(); int port=datagramPacket1.getPort(); byte[] data2=new String("Hello!").getBytes(); //2.创建数据报,包含响应给客户端的数据信息 DatagramPacket datagramPacket2=new DatagramPacket(data2,data2.length,inetAddress,port); //3.响应客户端 datagramSocket.send(datagramPacket2); //4.关闭资源 datagramSocket.close(); }}
1.定义发送的信息;
2.创建DatagramPacket,包含要发送的信息;
3.创建DatagramSocket;
4.发送数据;
public class UDPClient { public static void main(String[] args) throws IOException { /* * 向服务器端发送数据 */ // 1.定义服务器的地址、端口号、数据 InetAddress address = InetAddress.getByName("localhost"); int port = 8800; byte[] data = "用户名:admin;密码:123".getBytes(); // 2.创建数据报,包含发送的数据信息 DatagramPacket packet = new DatagramPacket(data, data.length, address, port); // 3.创建DatagramSocket对象 DatagramSocket socket = new DatagramSocket(); // 4.向服务器端发送数据报 socket.send(packet); /* * 接收服务器端响应的数据 */ // 1.创建数据报,用于接收服务器端响应的数据 byte[] data2 = new byte[1024]; DatagramPacket packet2 = new DatagramPacket(data2, data2.length); // 2.接收服务器响应的数据 socket.receive(packet2); // 3.读取数据 String reply = new String(data2, 0, packet2.getLength()); System.out.println("服务器响应是:" + reply); // 4.关闭资源 socket.close(); }}
小结:UDP的Socket通信就是将数据转换为字节,然后放到DatagramPacket(数据报)中,发送的时候需要指明接收者的IP地址和端口号;而接收的时候,用一个字节数组来缓存;
发送和接受都需要DatagramSocket(端对端通信类)对象来send()或者receive();
网络协议对速率、传输代码、代码结构、传输控制参数、出错控制等制定标准;
分层思想:同层间通信、上层调用下层而不再与下一层有联系;
传输层协议
IP协议是网络层的主要协议,支持网络间互为关联的协议;
URL:统一资源定位符,标识Internet上某一资源的地址
URL 是一个网页地址,可以由字母组成,如"www.baidu.com",或互联网协议(IP)地址:192.68.20.50:端口。
URL 只能使用ASCII 字符集来通过因特网进行发送。
scheme://host.domain:port/path/filename传输协议://主机名:端口号/(路径)/文件名(#片段名?参数列表)片段名:锚点参数列表格式:参数名=参数值&参数名=参数值...
定义在java.net包下;
URL常用方法
序号 | 方法描述 |
---|---|
1 | public String getProtocal() 获取URL的协议名 |
2 | public String getHost() 获取URL的主机名 |
3 | public String getPort() 获取URL的端口号 |
4 | public String getPath() 获取URL的文件路径 |
5 | public String getFile() 获取URL的文件名 |
6 | public String getQuery() 获取URL的查询名 |
转载地址:http://xrqzi.baihongyu.com/