网络编程 1
1.1软件架构
- c/s架构∶全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、美团app、360安全卫士等软件。
- B/s架构︰全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有IE、谷歌、火狐等。
1.要想实现网络通信,需要解决的三个问题:
- 问题1:如何准确地定位网络上一台或多台主机
- 问题2:如何定位主机上的特定的应用
- 问题3:找到主机后,如何可靠、高效地进行数据传输
2.实现网络传输的三个要素:(对应解决三个问题)
- 使用IP地址(准确地定位网络上一台或多台主机)
- 使用端口号(定位主机上的特定的应用)
- 规范网络通信协议(可靠、高效地进行数据传输)
3.通信要素1:IP地址
3.1 作用
IP地址用来给网络中的一台计算机设备做唯一的编号
3.2 IP地址分类
- IP地址分类方式1
- IPv4(占用4个字节)
- IPv6(占用16个字节)
- IP地址分类方式2
公网地址(万维网使用)和私有地址(局域网使用。以192.168开头)
3.3本地回路地址:127.0.0.1
3.4域名∶便捷的记录ip地址
- www.baidu.com
- www.atguigu.com
- www.bilibili.com
4.通信要素2:端口号
- 可以唯一标识主机中的进程(应用程序)
- 不同的进程分配不同的端口号
- 范围:0~65535
5.InetAddress的使用
5.1作用
InetAddress类的一个实例就代表一个具体的ip地址。
5.2实例化方式
- InetAddress getByName(String host)
- InetAddress getLocalHost()
5.3常用方法
- getHostName()
- getHostAddress()
//1.实例化
public void test1(){
try {
//getByName (String host) 获取指定ip对应的InetAddress的实例
InetAddress inet1 = InetAddress.getByName("192.168.23.31");
System.out.println(inet1);///192.168.23.31
InetAddress inet2 = InetAddress.getByName("www.baidu.com");
System.out.println(inet2);//www.baidu.com/36.155.132.31
//getLocalHost() 获取本地ip对应的InetAddress的实例
InetAddress localHost = InetAddress.getLocalHost();
//InetAddress localHost = InetAddress.getByName("127.0.0.1");
System.out.println(localHost);//星辰之海/10.8.246.3
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
public void test2() throws UnknownHostException {
InetAddress inet1 = InetAddress.getByName("www.baidu.com");
//
System.out.println(inet1.getHostName());//www.baidu.com
System.out.println(inet1.getHostAddress());//36.155.132.31
}
2.1 TCP协议与UDP协议
TCP协议:
-
TCP协议进行通信的两个应用进程:客户端、服务端。
-
使用TCP协议前,须先建立TCP连接,形成基于字节流的传输数据通道。传输前,采用“三次握手”方式,点对点通信,是可靠的
TCP协议使用重发机制,当一个通信实体发送一个消息给另一个通信实体后,需要收到另一个通信实体确认信息,如果没有收到另一个通信实体确认信息,则会再次重复刚才发送的消息。
-
在连接中可进行大数据量的传输
-
传输完毕,需释放已建立的连接,效率低UDP协议:**
UDP协议
- 进行通信的两个应用进程:发送端、接收端。
- 将数据、源、目的封装成数据包(传输的基本单位),不需要建立连接
- 发送不管对方是否准备好,接收方收到也不确认,不能保证数据的完整性,故是不可靠的。
- 每个数据报的大小限制在64K内
- 发送数据结束时无需释放资源,开销小,通信效率高
- 适用场景:音频、视频和普通数据的传输。例如视频会议
//例题1:客户端发送内容给服务端,服务端将内容打印到控制台上。
//客户端
public void client() throws IOException {
//创建一个Socket
InetAddress byName = InetAddress.getByName("10.8.246.3");//声明对方的ip地址
int port=8989;//声明对方的端口号
Socket socket = new Socket(byName,port);
//发送数掘
OutputStream os = socket.getOutputStream();
os.write("你好,我是客户端".getBytes());
//关闭socket,关闭流
socket.close();
os.close();
}
//服务端
public void server() throws IOException {
//创建一个ServerSocket
int port=8989;
ServerSocket serverSocket = new ServerSocket(port);
//调用accept(),接收客户端的Socket
Socket socket = serverSocket.accept();
System.out.println("服务器端已开启");
//接收数据
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
String s = new String(buffer, 0, len);
System.out.print(s);
}
System.out.println("\n数据接收完毕");
//关闭Socket、 ServerSocket,流
socket.close();
serverSocket.close();//真实不加
is.close();
}
改进
//例题1:客户端发送内容给服务端,服务端将内容打印到控制台上。
//客户端
public void test1() throws IOException {
//创建一个Socket
InetAddress byName = InetAddress.getByName("10.8.246.3");//声明对方的ip地址
int port=8989;//声明对方的端口号
Socket socket = new Socket(byName,port);
//发送数掘
OutputStream os = socket.getOutputStream();
os.write("你好,我是客户端".getBytes());
//关闭socket,关闭流
socket.close();
os.close();
}
//服务端
public void test2() throws IOException {
//创建一个ServerSocket
int port=8989;
ServerSocket serverSocket = new ServerSocket(port);
//调用accept(),接收客户端的Socket
Socket socket = serverSocket.accept();
System.out.println("服务器端已开启");
System.out.println("收到了来自于"+socket.getInetAddress().getHostAddress()+"的连接");
//接收数据
InputStream is = socket.getInputStream();
byte[] buffer = new byte[1024];
int len;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len=is.read(buffer))!=-1){
// 错误的,会乱码
// String s = new String(buffer, 0, len);
// System.out.print(s);
// 正确的
baos.write(buffer,0,len);
}
System.out.println(baos);
System.out.println("\n数据接收完毕");
//关闭Socket、 ServerSocket,流
socket.close();
serverSocket.close();//真实不加
is.close();
}
//注意:因为涉及到相关资源的关闭,需要使用try-catch-finally处理异常
//例题2:客户端发送文件给服务端,服务端将文件保存在本地。
//客户端
public void test1() throws IOException {
//1.创建Socket
//指明对方(即为服务器端)的ip地址和端口号
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
int port = 9090;
Socket socket = new Socket(inetAddress, port);
//2.创建File的实例、FileInputStream的实例
File file = new File("playgirl.jpg");
FileInputStream fis = new FileInputStream(file);
//3.通过Socket,获取输出流
OutputStream os = socket.getOutputStream();
//4.读写数据
byte[] buffer = new byte[1024];
int len;
while ((len=fis.read(buffer))!=-1){
os.write(buffer,0,len);
}
System.out.println("数据发送完毕");
//5.关闭Socket和相关的流
os.close();
fis.close();
socket.close();
}
//服务端
public void test2() throws IOException {
//1.创建ServerSocket
int port=9090;
ServerSocket serverSocket = new ServerSocket(port);
//2.接收来自于客户端的socket: accept()
Socket socket = serverSocket.accept();
//3.通过Socket获取一个输入流
InputStream is = socket.getInputStream();
//4.创建File类的实例、File0utputStream的实例
File file = new File("playgirl.copy.jpg");
FileOutputStream fos = new FileOutputStream(file);
//5.读写过程
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
System.out.println("接收完毕");
//6.关闭相关的Socket和流
fos.close();
is.close();
socket.close();
serverSocket.close();
}
//例题3:从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功"给客户端。并关闭相应的连接。
//客户端
public void test3() throws IOException {
//1.创建Socket
//指明对方(即为服务器端)的ip地址和端口号
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
int port = 9090;
Socket socket = new Socket(inetAddress, port);
//2.创建File的实例、FileInputStream的实例
File file = new File("playgirl.jpg");
FileInputStream fis = new FileInputStream(file);
//3.通过Socket,获取输出流
OutputStream os = socket.getOutputStream();
//4.读写数据
byte[] buffer = new byte[1024];
int len;
while ((len=fis.read(buffer))!=-1){
os.write(buffer,0,len);
}
System.out.println("数据发送完毕");
//客户端表明不再继续发送数据
socket.shutdownOutput();
//5.接收来着于服务器端的数据
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer1 = new byte[5];
int len1;
while ((len1= is.read(buffer1))!=-1){
baos.write(buffer1,0,len1);
}
System.out.println(baos);
//5.关闭Socket和相关的流
baos.close();
is.close();
os.close();
fis.close();
socket.close();
}
//服务端
public void test4() throws IOException {
//1.创建ServerSocket
int port=9090;
ServerSocket serverSocket = new ServerSocket(port);
//2.接收来自于客户端的socket: accept()
Socket socket = serverSocket.accept();
//3.通过Socket获取一个输入流
InputStream is = socket.getInputStream();
//4.创建File类的实例、File0utputStream的实例
File file = new File("playgirl.copy1.jpg");
FileOutputStream fos = new FileOutputStream(file);
//5.读写过程
byte[] buffer = new byte[1024];
int len;
while ((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
System.out.println("接收完毕");
//6.服务端发送数据给客户端
OutputStream os = socket.getOutputStream();
os.write("您的图很好,谢谢".getBytes());
//7.关闭相关的Socket和流
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
UDP协议:
.UDP协议进行译信的两个应用进程:发送端、接收端。
//发送端
public void test5() throws IOException {
//1.创建DatagramSocket的实例
DatagramSocket ds = new DatagramSocket();
//2.将数据、目的地的ip,目的地的端口号都封装在DatagramPacket数据报中
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
int port= 9090;
byte[] bytes="我是发送端".getBytes();
DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, inetAddress, port);
///发送数据
ds.send(packet);
ds.close();
}
//
public void test6() throws IOException {
//1.创建DatagramSocket的实例
int port=9090;
DatagramSocket ds = new DatagramSocket(port);
//2.创建数据报的对象,用于接收发送端发送过来的数据
byte[] buffer = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
//3.接收数据
ds.receive(packet);
//4.获取数据,并打印到控制台上
String s = new String(packet.getData(), 0, packet.getLength());
System.out.println(s);
ds.close();
}
3-URL编
URL(Uniform Resource Locator):统一资源定位符(种子)
1.作用:
一个具体的url就对应着互联网上某一资源的地址。
2 URL的格式:
http: / /192.168.21.107:8080/examples/abcd.jpg?name=Tom
应用层协议 ip地址 端口号 资源地址 参数列表
6.2 URL类常用方法
一个URL对象生成后,其属性是不能被改变的,但可以通过它给定的方法来获取这些属性:
- public String getProtocol() 获取该uRL的协议名
- public String getHost() 获取该URL的主机名
- public String getPort() 获取该URL的端口号
- public String getPath() 获取该uURL的文件路径
- public String getFile() 获取该URL的文件名
- public String getQuery()获取该URL的查询名
//需求:将URL代表的资源下载到本地
public void test7() throws IOException {
//1.获取URL实例
URL url = new URL("http://127.0.0.1:8080/examples/abcd.jpg");
//2.建立与服务器端的连接
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//3.获取输入流、创建输出流
InputStream is = urlConnection.getInputStream();
File file = new File("dest.jpg");
FileOutputStream fos = new FileOutputStream(file);
//4.读写数据
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.close();
is.close();
urlConnection.disconnect();
}
网络通信协议
·在传输层中涉及到两个协议:TCP、UDP。二者的对比
- TCP:可靠的连接(发送数据前,需要三次握手、四次挥手),进行大数据量的传输,效率低。
- UDP:不可靠的连接(发送前,不需要确认对方是否在)、使用数据报传输(限制在64kb以内)、效率高。
7.URL编程
- Java后台:将写好的Java程序部署在Tomcat服务器。启动Tomcat服务器。
- 前台:使用浏览器进行访问。需要使用url。(HTML+CSS+JavaScript).
- URL的作用:定位互联网上某一资源的地址。
- URL的格式: