网络编程

网络编程

1. 计算机网络的概念

网络即将不同区域的电脑连接到一起, 组成局域网、城 域网或广域网。把分布在不同地理区域的计算机与专门 的外部设备用通信线路互连成一个规模大、功能强的网 络系统,从而使众多的计算机可以方便地互相传递信 息,共享硬件、软件、数据信息等资源。

在这里插入图片描述

主要功能如下: 资源共享 信息传输与集中处理 均衡负荷与分布处理

2. 网络通信协议

计算机网络中实现通信必须有一些约定即通信协议,对 速率、传输代码、代码结构、传输控制步骤、出错控制 等制定标准。显然,每一行数据都有“姓名”、“基本工 资”等“列”,也都有标准的“晨会动作”。
网络通信协议由 三个要素组成 : 语义 、 语法 、 时序 语义表示要做什么,语法表示要怎么做,时序表示做的 顺序。

3. 网络通信接口

为了使两个结点之间能进行对话,必须在它们之间建立 通信工具(即接口),使彼此之间能进行信息交换。接口 包括两部分:
硬件装置: 实现结点之间的信息传送;
软件装置: 规定双方进行通信的约定协议

4. 网络分层

由于结点之间联系很复杂,在制定协议时,把复杂成份 分解成 一些简单的成份,再将它们复合起来。最常用的 复合方式是层次方式,即同层间可以通信、上一层可以 调用下一层,而与再下一层不发生关系。

4.1. 通信协议的分层

在这里插入图片描述
在这里插入图片描述

4.2. 封装

封装:从上往下,加入相关层的协议控制信息

在这里插入图片描述

4.3. 拆封

拆封:获取数据,从下往上,去除相关层的协议的控制信 息

在这里插入图片描述

5. IP地址

( IP) 是 Internet Protocol 的外语缩写, 网络之间互连 的协议也就是为计算机网络相互连接进行通信而设计的 协议。 在因特网中,它是能使连接到网上的所有计算机 网络实现相互通信的一套规则,规定了计算机在因特网 上进行通信时应当遵守的规则。任何厂家生产的计算机 系统,只要遵守 IP 协议就可以与因特网互连互通。
端口:区分数据流向的软件 0-65535 不要使用 1024 以下 的端口 ,每一个协议拥有自己的端口,在同一个协议下 端口不能重复 FTP:21 HTTP:80
//封装计算机的 ip 地址和 DNS( Domain Name
System,域名系统) ,没有端口。
InetAddress.getLocalHost();
InetAddress.getByName("www.163.com");
InetAddress.getByName("223.87.1.58")
getHostAddress() //返回 ip 地址
getHostName() //返回域名|本机为计算机名

6. 端口(port)和url

端口是虚拟的概念,并不是说在主机上真的有若干个端 口。通过端口,可以在一个主机 上运行多个网络应用程 序。可以类比为:IP 相当于公司,端口相当于公司各部 门,URL相当于各部门的人员 包含端口,用于 socket 通信的

//1) 、获取对象
InetSocketAddress(String hostname, int port)
InetSocketAddress(InetAddress addr, int port)
//2) 、方法
getAddress() //返回 InetAddress 对象
getPort() //返回端口
getHostName() //返回域名

6.2. url

URL全称是Uniform Resource Location,也就是统一资源 位置。实际上,URL就是一种特殊的URI,它除了标识一 个资源,还会为资源提供一个特定的网络位置,客户端 可以通过它来获取URL对应的资源。
URL所表示的网络资源位置通常包括用于访问服务器的 协议(如http、ftp等)、服务器的主机名或者IP地址、以及资源文件在该服务器上的路径。典型的URL例如http://localhost:port/myProject/index.htm
protocol://userInfo@host:port/path?query#fragment
协议://用户信息@主机名:端口/路径?查询#锚点

IP地址唯一标识了Internet上的计算机,而URL则标识了 这些计算机上的资源。类 URL 代表一个统一资源定位 符,它是指向互联网“资源”的指针。资源可以是简单的 文件或目录,也可以是对更为复杂的对象的引用,例如 对数据库或搜索引擎的查询。
为了方便程序员编程,JDK中提供了URL类,该类的全 名是 java.net.URL ,有了这样一个类,就可以使用它 的各种方法来对URL对象进行分割、合并等处理。
java.net.URL 类(后面直接叫URL)是JDK对URL的统一 抽象,它是一个final修饰的类,也就是不允许派生子 类。

6.3. 网络爬虫原理

public static void main(String[] args) throws
IOException {
URL url=new URL("http://www.baidu.com");//
主页 默认资源
//获取资源 网络流 可能会出现乱码:1、字
节数不够 2、编码解码格式不统一
/*InputStream is=url.openStream();
byte[]flush=new byte[1024];
int len=0;
while(-1!=(len=is.read(flush))){
System.out.println(new
String(flush,0,len));
}
is.close();*/
BufferedReader br=new BufferedReader(new
InputStreamReader(url.openStream(),"utf-8"));
BufferedWriter bw=new BufferedWriter(new
OutputStreamWriter(new
FileOutputStream("baidu2.html"),"utf-8"));
String msg=null;
while((msg=br.readLine())!=null){
//将网络内容下载到本地。然后进行数据分析,建
立索引,这也是搜索引擎的第一步。
bw.append(msg);
bw.newLine();//新增方法 插入换行符
}
bw.flush();//强制刷出
bw.close();
br.close();
}

7. 传输层协议

7.1. 协议
TCP:TCP(transfer control protocol) 打电话 面向连接、 安全、可靠,效率低
UDP:UDP(UserDatagramProtocol ) 发送短信 非面向连 接、不安全、数据可能丢失 、效率高

7.2. UDP编程: DatagramSocket, DatagramPacket

UserDatagramProtocol,一种无连接的传输层协议,提供 面向事务的简单不可靠信息传送服务。其特点为:非面向 连接;传输不可靠;数据可能丢失。

在这里插入图片描述

DatagramSocket:用于发送或接收数据报的数据报包:
当服务器要向客户端发送数据时,需要在服务器端产生 一个DatagramSocket对象,在客户端产生一个 DatagramSocket对象。服务器端的DatagramSocket将 DatagramPacket发送到网络上,然后被客户端的 DatagramSocket接收。
DatagramSocket有两种构造函数。一种是无需任何参数 的,常用于客户端。另一种需要指定端口,常用于服务 器。常用方法: send , receive , close
DatagramPacket:数据容器(封包)的作用: 常用方法:构造函数、getAddrress(获取发送或接收方计 算机的Ip地址)、getData(获取发送或接收的数据), setData(设置发送的数据)

7.2.1. 服务器端

①创建服务器 DatagramSocket类 +指定端口 (定义服 务器端的监听端口)

②准备接收容器 字节数组 +封装成DatagramPacket数 据报 (准备容器接收数据)

③接收数据

④分析数据

⑤释放资源

7.2.2. 客户端

①创建客户端 DatagramSocket类 +指定端口 (定义客 户端的监听端口)

②准备数据

字节数组

③封装成数据包 需要指定包发送的地址+端口 即服务 器地与端口 (打包要发送的数据)

④发送数据

⑤释放资源

服务器端示例
public class Server {
public static void main(String[] args)
throws Exception {
// 创建数据报包 工具
DatagramSocket ds = new
DatagramSocket(8999);
// 准备接收数据的容器空间
byte[] b = new byte[1024];
// 数据报
DatagramPacket dp = new
DatagramPacket(b,b.length);
ds.receive(dp); //阻塞式方法
String string = new
String(dp.getData(),0,dp.getLength());
//dp.getLength()返回实际收到的数据的字节数
System.out.println(string);
ds.close();
}
}

客户端示例

public class Client {
public static void main(String[] args)
throws Exception {
// 创建要发送数据报包的工具,我本身占用9000
端口向外面机器发数据包
DatagramSocket ds = new
DatagramSocket(9000);
byte[] b = "aaaa".getBytes();
//必须告诉数据包要发到哪里去, 封装数据时才
指定 目标电脑以及端口
DatagramPacket dp = new
DatagramPacket(b,b.length,new
InetSocketAddress("localhost",8999));
ds.send(dp);
ds.close();
}
}

7.3. TCP 编程:ServerSocket, Socket

transfer control protocol,一种面向连接(连接导向)的、 可靠的、基于字节流的传输层(Transport layer)通信协议 的点到点的通信 。TCP 三次握手(Three-way Handshake), 类似于拨打电话。
特点
特点 基于 tcp 协议,建立稳定连接的点对点的通信;实时、快 速、安全性高、占用系统资源多、效率低;“请求-响应”模 式:

a)、客户端:在网络通讯中,第一次主动发起通讯的 程序被称作客户端(Client)程序

b)、服务器:第一次通讯中等待连接的程序被称作服 务器端(Server)程序

套接字是一种进程间的数据交换机制。这些进程既可以 在同一机器上,也可以在通过网络连接的不同机器上。 换句话说,套接字起到通信端点的作用。单个套接字是 一个端点,而一对套接字则构成一个双向通信信道,使 非关联进程可以在本地或通过网络进行数据交换。一旦 建立套接字连接,数据即可在相同或不同的系统中双向 或单向发送,直到其中一个端点关闭连接。

套接字与主机地址和端口地址相关联。主机地址就 是客户端或服务器程序所在的主机的ip地址。端口地址 是指客户端或服务器程序使用的主机的通信端口。

实际上,套接字只是计算机上已编号的端口。如果发送 方和接收方计算机确定好端口,他们就可以通信了

7.3.1. 相关类

InetAddress:封装计算机的ip地址和DNS(没有端口信 息!)

这个类没有构造函数。如果要得到对象,只能通过静态 方法: getLocalHost , getByName , getAllByName , getAddress , getHostNameg

//使用getLocalHost方法创建InetAddress对象
// InetAddress addr =
InetAddress.getLocalHost();
//
System.out.println(addr.getHostAddress()); //
返回:192.168.1.110
//
System.out.println(addr.getHostName()); //输出
计算机名
//根据域名得到InetAddress对象
// InetAddress addr =
InetAddress.getByName("www.163.com");
//
System.out.println(addr.getHostAddress()); //
返回 163服务器的ip:61.135.253.15
//
System.out.println(addr.getHostName()); //输
出:www.163.com
//根据ip得到InetAddress对象
InetAddress addr =
InetAddress.getByName("61.135.253.15");
System.out.println(addr.getHostAddress()); //
返回 163服务器的ip:61.135.253.15
System.out.println(addr.getHostName()); //输出
ip而不是域名。如果这个IP地 址不存在或DNS服务器不允许进
行IP地址和域名的映射,getHostName方法就直接返回这个
IP地址。
InetSocketAddress:包含IP和端口,常用于SOCKET通信。
InetSocketAddress socketAddress = new
InetSocketAddress("127.0.0.1",8080);
InetSocketAddress socketAddress2 = new
InetSocketAddress("localhost",9000);
System.out.println(socketAddress.getHostName()
);
System.out.println(socketAddress2.getAddress()
);

7.3.2. 服务器端

①创建服务器 指定端口

创建服务器ServerSocket,在创建时,定义 ServerSocket的监听端口(在这个端口接收客户端发来 的消息!)

②等待客户端连接

ServerSocket调用accept()方法,使之处于阻塞状态

③分析接收数据

利用Socket进行接收和发送数据

7.3.3. 客户端

①连接服务器: 创建客户端 +指定服务器地址 +端口

创建客户机Socket,并设置服务器的ip及端口,客 户机发出连接请求,建立连接。

②发送数据

通过Socket发送数据,和接收数据

服务器端示例

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 最简单的服务器端代码
*
*/
public class BasicSocketServer {
public static void main(String[] args) {
try {
//建立服务器端套接字
ServerSocket serverSocket = new
ServerSocket(8888); //tcp端口一共多少个??
//监听,等待客户端请求,并愿意接收连接。
System.out.println("服务端建立监
听");
Socket socket =
serverSocket.accept();
//通过流向客户端发送数据
// ObjectOutputStream oos
= new
ObjectOutputStream(socket.getOutputStream());
//
oos.writeObject("aaaaa");
// oos.close();
BufferedWriter bw = new
BufferedWriter(new
OutputStreamWriter(socket.getOutputStream()));
bw.write("hhhh");
bw.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
                  

客户端示例

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 最简单的Socket客户端
*
*/
public class BasicSocketClient {
public static void main(String[] args) {
try {
//指定的是所要连接的服务器的ip和端口。而
不是自己机器的端口。发送端口是随机的。
Socket socket = new
Socket(InetAddress.getLocalHost(),8888);
// ObjectInputStream ois
= new
ObjectInputStream(socket.getInputStream());
// String string =
(String) ois.readObject();
//
System.out.println(string);
BufferedReader br = new
BufferedReader(new
InputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());
br.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值