博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络编程
阅读量:3960 次
发布时间:2019-05-24

本文共 10614 字,大约阅读时间需要 35 分钟。

目录

网络编程

(1)概述

网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。

实现网络中的主机通信

1.通信双方的地址:IP、端口号

2.一定的规则:网络通信协议(OSI参考模型、TCP、IP协议)

(2)IP和端口号

IP地址:对应InetAddress类,一个对象代表一个IP地址;

  • IP地址唯一标识Internet上的计算机
  • 本地回环地址为(hostAddress):127.0.0.1
  • 本地主机名(hostName):localhost

IP地址分类

IPV4:4个字节组成

IPV6:16个字节,写成8个整数,每个整数用4位十六进制数表示,数之间用冒号隔开(X:X:X:X:X:X:X:X,X=_ _ _ _)

也可以分为

公网地址:万维网使用

私有地址:局域网使用,192.168开头,范围是0.0——255.255

InetAddress

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

端口号

  • 标识正在计算机上运行的进程;
  • 不同的进程对应不同的端口号;
  • 端口地址是16比特,可以有在0—65535范围内的端口号;

端口分类

1.公认端口:0——1023,系统的保留端口,程序尽可能别使用这些端口;

2.注册端口:1024——49151

3.动态/私有端口:49152——65515

特定的端口号:MySQl 3306;Tomcat 8080

(3)Socket

IP地址和端口号的组合得到一个网络套接字:Socket;

Socket(套接字)用来描述IP地址和端口,是通信链的句柄,应用程序可以通过Socket向网络发送请求或者应答网络请求;

Socket是支持TGP/IP协议的网络通信的基本操作单元,是对网络通信过程中端点的抽象表示,包含了进行网络通信所必须的五种信息:

1.连接所使用的协议;

2.本地主机的IP地址;

3.本地远程的协议端口;

4.远地主机的IP地址;

5.远地进程的协议端口;

Socket通信模型

img

Socket通信实例

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(); } }}

ServerSocket类

服务器应用程序通过使用 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 地址和端口号)。

Socket类

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 关闭此套接字。

TCP的Socket通信

1.创建ServerSocket和Socket;

2.打开连接到的Socket的输入/输出流;

3.按照协议对Socket进行读写操作;

4.关闭输入输出流以及Socket;

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(); }

Socket客户端

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的Socket通信

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();

(4)网络协议

网络协议对速率、传输代码、代码结构、传输控制参数、出错控制等制定标准;

分层思想:同层间通信、上层调用下层而不再与下一层有联系;

传输层协议

  • 传输控制协议:TCP(可靠)——3次握手
  • 用户数据报协议:UDP(不可靠)

IP协议是网络层的主要协议,支持网络间互为关联的协议;

(5)URL编程

URL:统一资源定位符,标识Internet上某一资源的地址

URL 是一个网页地址,可以由字母组成,如"www.baidu.com",或互联网协议(IP)地址:192.68.20.50:端口。

URL 只能使用ASCII 字符集来通过因特网进行发送。

URL语法规则

scheme://host.domain:port/path/filename传输协议://主机名:端口号/(路径)/文件名(#片段名?参数列表)片段名:锚点参数列表格式:参数名=参数值&参数名=参数值...

URL类

定义在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/

你可能感兴趣的文章
Linux文件系统目录结构的详细解说(一)
查看>>
TIME_WAIT状态的意义
查看>>
千万不要把 bool 设计成函数参数
查看>>
linux文件属性及权限详解
查看>>
Find 命令使用详解
查看>>
Ext4,Ext3的特点和区别
查看>>
Linux文件系统目录结构的详细解说(二)
查看>>
Linux umount 报 device is busy 的处理方法
查看>>
一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素,要求O(1)空间和O(n)时间。
查看>>
提供机制而不是策略
查看>>
内核中断机制
查看>>
内核抢占
查看>>
编译linux内核源码 ubuntu
查看>>
epoll使用详解
查看>>
epoll
查看>>
The AnimationClip 'Walk' used by the Animation component 'Pig' must be marked as Legacy.
查看>>
《Linux内核设计与实现》- Linux的进程
查看>>
《Linux内核设计与实现》- 进程的调度
查看>>
inet_ntoa()
查看>>
POSIX消息队列mq_open问题
查看>>