黑马程序员技术交流社区

标题: [石家庄校区]网络简单编程介绍 [打印本页]

作者: 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