目录
心情日记
又要考试了,还是企业出题——大考。害怕。。。
重点归纳
- 网络编程(网络通信)
- 通过浏览器访问服务器
知识点
网络编程(网络通信)
服务器:是一台电脑,低配版
客户端:是一台电脑,是手机,是平板,是网页
我们可以自己的电脑上搭建服务器环境,模拟客户端和服务器之间的网络通信
Socket编程
Socket编程是建立在TPC/IP协议上的
同一网络环境下,如何访问其他主机?
通过 IP地址 加 端口号 的形式访问其他主机
怎么查看自己的IP地址
通过CMD,ipconfig查看ipv4地址,是当前局域网下的ip地址
特点
一台电脑可以有多个端口号,每个端口号对应的程序也可以不同
当我们用ip地址+端口号访问一个指定程序的时候,端口号不同,程序不同
Socket通信
接下来就要在自己的电脑开辟一个端口号,这个端口号就是服务器的端口
简单的服务器读取客户端信息
@Test
public void server() throws IOException {
//创建了一个服务器对象,绑定在8888端口
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器已经启动");
//服务器在等待客户端连接
Socket socket = serverSocket.accept();
//读取客户端发来的信息,读流
InputStream inputStream = socket.getInputStream();
byte [] buffer = new byte[1024*1024];
int len;
while ((len = inputStream.read(buffer)) != -1){
System.out.println("服务器已经接受了客户端的数据" + new String(buffer,0,len));
}
//释放资源
inputStream.close();
socket.close();
}
@Test
public void client() throws IOException {
//创建了一个Socket通信的客户端
Socket socket = new Socket();
//第一个参数就是获取当前电脑的IP地址
//第二个参数就是服务器的端口号
socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(),8888));
//客户端发送数据给服务器
OutputStream outputStream = socket.getOutputStream();
String data = "hello server!";
outputStream.write(data.getBytes());
System.out.println("客户端已经发送数据" + data);
outputStream.close();
socket.close();
}
服务器接收客户端信息,再返回信息给客户端,客户端接收信息
@Test
public void server() throws IOException {
// 创建了一个服务器对象,绑定在8888端口
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器已启动...");
// 服务器在等待客户端连接
Socket socket = serverSocket.accept();
// 读取客户端发送过来的信息
InputStream inputStream = socket.getInputStream();
// InputStream inputStream1 = new FileInputStream("");
OutputStream outputStream = new FileOutputStream("d:/Pointofix.exe");
// 我们要再获取一个输出流,这个输出流是为了给客户端返回数据
OutputStream clientOutputStream = socket.getOutputStream();
byte [] buffer = new byte[1024 * 1024];
int len;
while((len = inputStream.read(buffer)) != -1){
// 接收信息,接的是什么信息?
// 看输入流是怎么来的?
// 我们现在的输入流是怎么来的?
// 通过socket获取到的
// socket是怎么来的?
// socket是通过服务器启动之后,接到的客户端连接
// 我们的输入流就是客户端的输入流
// 因为我们现在接收的是一个文件
// 我们需要把这个文件另存
// 我们需要构建一个输出流,把这个文件保存在硬盘上
outputStream.write(buffer,0,len);
}
System.out.println("文件接收成功...");
// 给客户端返回一个数据
clientOutputStream.write("文件已成功保存到服务器...".getBytes());
// 释放资源
inputStream.close();
outputStream.close();
socket.close();
}
@Test
public void client() throws IOException {
// 创建了一个Socket通信的客户端
Socket socket = new Socket();
// 第一个参数就是获取当前电脑的IP地址
// 第二个参数就是服务器的端口号
socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(),8888));
// 客户端发送数据给服务器
OutputStream outputStream = socket.getOutputStream();
File file = new File("e:/Pointofix.exe");
InputStream inputStream = new FileInputStream(file);
// 我们现在要读取的是服务器的数据,就需要构建一个从服务器来的输入流
InputStream serverInputStream = socket.getInputStream();
// 要发送的文件
byte [] buf = new byte[1024 * 1024];
int len;
while((len = inputStream.read(buf)) != -1){
// 把读取到的文件循环发送给服务器
// 输出流把文件写出去,写到哪里去了?
// 输出流,首先要看这个输出流是怎么来的,就能够确定这个内容要输出到哪里?
// 我们现在的输出流是通过socket获取到的
// 所以说我们现在的写的操作就是把文件写给服务端
outputStream.write(buf,0,len);
}
System.out.println("文件发送成功...");
// 要通知服务器文件已发送完毕,下面的操作是等待服务器的回复
// 通知服务器数据已经发送完毕
/* 如果没有这行代码会进入死循环,下面的代码也是一个读的代码,
服务器会认为客户端传输信息没有传完,而实际上下面读的代码是
用来接收服务器返回的信息的,会一直等服务器的返回信息,这样
两边就都在等。。。
*/
socket.shutdownOutput();
// 接收服务器回传的数据
byte [] serverBuf = new byte[1024 * 1024];
int serverLen;
while((serverLen = serverInputStream.read(serverBuf)) != -1){
System.out.println(new String(serverBuf,0,serverLen));
}
inputStream.close();
outputStream.close();
socket.close();
}
UDP:不可靠的传输协议
效率非常长高,但容易丢数据的传输手段,只是快,后果严重
@Test
public void client() throws IOException {
DatagramSocket Socket = new DatagramSocket();
String str = "我通过UDP协议发的消息。。。";
byte [] data = str.getBytes();
//构建成了一个数据范文
//第一个参数就是要发送的数据
//第二个参数就是要从哪法
//第三个参数就是发多长
//第四个参数就是指定服务器的ip地址
//第五个参数就是服务器的端口号
DatagramPacket packet = new DatagramPacket(data,0,data.length, InetAddress.getLoopbackAddress(),9999);
//发送数据
Socket.send(packet);
System.out.println("数据发送成功!!!");
Socket.close();
}
@Test
public void server() throws IOException {
//服务器指定端口
DatagramSocket socket = new DatagramSocket(9999);
byte [] buffer = new byte[1024*1024];
DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
socket.receive(packet);
System.out.println(new String(packet.getData(),0,packet.getLength()));
socket.close();
}
面试题
TCP/IP协议和UDP的区别?
TCP/IP:客户端和服务器要有稳定连接(三次握手,四次挥手)、要用到输入输出流接收和传送信息,
服务器不开,直接开客户端会报错
UDP:不需要连接,不需要IO流,直接根据服务器地址、端口号发送信息
只单纯的发送/接收信息,有没有信息都在发送/接收
URL工具类
格式: 协议 主机名 端口号 资源地址
一个URL对应着互联网的一个资源网址
URL:https://www.163.com/
URL:https://192.168.1.1:8888/goods
public static void main(String[] args) {
try {
URL url = new URL("https://192.168.1.1:8888/demo/list.html?usenrame=123&password=123456");
//获取协议
System.out.println(url.getProtocol());
//获取主机地址
System.out.println(url.getHost());
//获取端口号
System.out.println(url.getPort());
//地址
System.out.println(url.getPath());
//拿到文件---就是端口号后面所有的信息
System.out.println(url.getFile());
//查询参数---?后面的内容
System.out.println(url.getQuery());
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
InetAddress工具类
public static void main(String[] args) {
try {
InetAddress inet1 = InetAddress.getByName("192.168.1.1");
System.out.println(inet1);
InetAddress inet2 = InetAddress.getByName("www.baidu.com");
System.out.println(inet2);
// 获取本地ip
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);
// 获取本机的主机名
System.out.println(localHost.getHostName());
System.out.println(localHost.getHostAddress());
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
软件架构
- C/S架构:Client/Server客户端/服务器,QQ,360,腾讯会议,游戏
- B/S架构:Browser/Server浏览器/服务器,
移动互联,手机端为主,C/S架构,
Java两种架构都可以做,主要要做的就是架构中的Server端。
1.静态资源:所有用户访问后,得到的结果都是一样的。html
2.动态资源:每个用户访问后,得到的结果可能不一样。爱奇艺,
web服务器
格式:接收用户的请求,处理请求,给出响应。
通过浏览器访问我们的ServerSocket服务器,我们用浏览器通过IP地址 + 端口号
给ServerSocket服务器发起了请求:我要访问服务器!!!
(请求)
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
// 等待客户端的连接
Socket accept = serverSocket.accept();
// 获取一个输入流来读取客户端发送的数据
InputStream inputStream = accept.getInputStream();
byte [] buf = new byte[1024];
int len;
while((len = inputStream.read(buf)) != -1){
System.out.println(new String(buf,0,len));
}
inputStream.close();
accept.close();
}
端口号自己定义,怎么获得IP地址?
本机的IP地址:
1.cmd---ipconfig
2.127.0.0.1---本机(个人建议,任何情况都好使)
3.localhost---本机(前提条件:你的电脑要联网,激活一下网卡)
运行以上代码发现,我们什么信息也没发送,但是我们通过浏览器访问我们的ServerSocket,得到了一堆信息, 通过一些信息:
User-Agent:告诉服务器我是从什么样的客户端来的。
Host: 127.0.0.1:8080,主机地址,目标主机。
可以推断:貌似浏览器也是通过Socket和我们的服务器建立了TCP连接
其实发送过来的信息叫报文,是浏览器传递过来的一些消息。
我们称之为“请求”,而且这个请求格式满足了http的协议。
而服务器收到请求后回给浏览器做出响应,需要遵循浏览器的格式要求:
一次请求和响应称为会话:
请求:客户端--->服务器
响应:服务器--->客户端
(响应)
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器启动成功...");
Socket server = serverSocket.accept();
OutputStream outputStream = server.getOutputStream();
// 按照http协议的格式封装一个报文数据
String response = "HTTP/1.1 200 OK\r\n"+
"Content-Length: 39\r\n" +
"Content-Type: text/html;charset=UTF-8\r\n\r\n" +
"<h1>hello server</h1>";
outputStream.write(response.getBytes());
outputStream.flush();
// 这个流不要着急关,因为突然的关闭会导致浏览器和服务器断开连接
}
重定向
假如我要访问的是www.baidu.com,结果页面展示的是www.jd.com
重定向会重新定位到新的页面,而且地址栏的地址也会随之变化。
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器启动成功...");
Socket server = serverSocket.accept();
OutputStream outputStream = server.getOutputStream();
// 按照http协议的格式封装一个报文数据
String response = "HTTP/1.1 302 Moved Temporarily\r\n"+
"Location: https://www.baidu.com\r\n\r\n";
outputStream.write(response.getBytes());
outputStream.flush();
// 这个流不要着急关,因为突然的关闭会导致浏览器和服务器断开连接
}