黑马程序员技术交流社区
标题:
[石家庄校区]网络简单编程介绍
[打印本页]
作者:
heifachangcun
时间:
2018-12-2 15:20
标题:
[石家庄校区]网络简单编程介绍
网络编程三要素:
1. 通信协议 TCP
2. IP地址
3. 端口号
版本:
IPv4: 192.168.1.2
IPv6: ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
特殊的IP地址: "127.0.0.1", "localhost", 都代表自己的电脑
常用DOS命令:
// 查看自己电脑的IP地址
ipconfig
// 查看是否能连接到指定IP地址
ping IP地址
ping 192.168.31.2
端口号(门牌号)
端口号的取值范围: 0~65535的整数, 其中0~1024不建议使用
注意:
通信的两端是2个计算机中的2个程序在相互通信, 所以2个程序都要有端口号. 端口号可以相同, 也可以不同,相互之间能识别就行
软件结构介绍
C/S结构:
B/S结构:
网络通信协议
网络编程过程中需遵守的规则
网络通信协议分类
UDP: User Datagram Protocol, 用户数据报协议
特点:
1. 无连接的不可靠协议
2. 数据按包发送, 64K一个包
3. 速度快效率高, 容易丢包
用于视频直播, 网络电话
TCP: Transmission Control Protocol, 传输控制协议
特点:
1. 需要建立连接的可靠协议 电话
2. 数据传输无大小限制
3. 速度慢效率低 重发机制
用于文件下载, 浏览网页
TCP通信的三次握手
: TCP协议中, 在发送数据的准备阶段, 客户端与服务器之间的三次交互, 以保证连接的可靠
1. 客户端向服务端发送验证信息, 等待服务器确认
2. 服务端收到验证信息后, 回复客户端验证信息, 同时发送自己的一条验证信息
3. 客户端收到服务端回复的信息, 确认自己之前发的信息无误, 并再次向服务器发回服务端的验证信息
TCP通信方式概述
服务端(ServerSocket)可以通过 accept() 方法等待一个客户端(Socket)主动连接, 从而得到一个客户端对象(Socket), 来识别不同的客户端
服务端(ServerSocket)没有IO流, 是通过获取到"每个客户端对象(Socket)的IO流对象"来进行通信的.
使用"客户端的InputStream"读取客户端发来的数据
使用"客户端的OutputStream"向客户端回写数据
模拟Web服务器: 代码实现
需求:
使用ServerSocket实现Web服务器
具体步骤:
将web目录赋值粘贴到当前模块中
创建ServerSocket对象, 监听8080端口
使用 while(true) 死循环, 在循环中调用ServerSocket对象的 accept() 方法, 获取客户端Socket对象
在循环中创建线程并 start(), 在线程中传入Runnable的匿名内部类对象
Runnable匿名内部类中编写读取请求返回页面的代码:
1. 通过客户端socket获取InputStream, 经过转换流传递给BufferedReader, 便于读取一行字符串
BufferedReader br = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
2. 使用BufferedReader只读一行字符串即可, 然后按照空格切割字符串, 获取数组1索引的内容, 然后
从1索引截取字符串到末尾
即: GET /day11/web/index.html HTTP/1.1 获取其中的 day11/web/index.html
3. 创建FileInputStream指向截取出来的字符串作为文件路径
4. 通过客户端socket对象获取OutputStream, 先写入以下内容:
OutputStream os = socket.getOutputStream();
os.write("HTTP/1.1 200 OK\r\n".getBytes());
os.write("Content-Type: text/html\r\n".getBytes());
os.write("\r\n".getBytes());
5. 然后使用一次读取一个byte[]数组方式, 通过刚才创建的FileInputStream对象和socket获取的
OutputStream对象, 边读文件边写回客户端
6. 关闭FileInputStream和socket, 释放资源
// 模拟Web服务器
public class WebServer {
public static void main(String[] args) throws IOException {
// 创建服务端ServerSocket
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("Web服务器已启动...");
// 循环接收浏览器请求
while (true) {
Socket clientSocket = serverSocket.accept();
// 在子线程中来读取请求的文件返回给浏览器
new Thread(new Runnable() {
@Override
public void run() {
try {
// 先获取网络字节输入流, 用来读取浏览器的请求
InputStream is = clientSocket.getInputStream();
// 将网络字节输入流转换为缓冲字符输入流, 便于读取一样字符串
BufferedReader br = new BufferedReader(new
InputStreamReader(is));
// 读取一行字符串
String line = br.readLine();
// 按照空格切割
String[] arr = line.split(" ");
// 获取中间的元素, 并去掉开头的/ 得到html文件的路径
String htmlPath = arr[1].substring(1);
// 创建文件字节输入流, 用于读取html文件内容
FileInputStream fis = new FileInputStream(htmlPath);
// 获取网络字节输出流, 用于向浏览器回写文件内容
OutputStream os = clientSocket.getOutputStream();
// 先回写固定的HTTP响应行和响应头
os.write("HTTP/1.1 200 OK\r\n".getBytes());
os.write("Content-Type: text/html\r\n".getBytes());
os.write("\r\n".getBytes());
// 然后再边读边回写文件
byte[] bytes = new byte[1024];
int len;
while ((len = fis.read(bytes)) != -1) {
os.write(bytes, 0, len);
}
// 关流释放资源
fis.close();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2