Java笔记(11)-Socket编程

  1. 常见默认端口号
1. 网络端口:80
2. 数据库端口:MySQL:3306 , Oracle:1521
3. Tomcat服务器:8080
  1. TCP通信程序
1. 服务器端启动
2. 等待客户端发起连接请求
3. 建立逻辑连接后,该逻辑连接中包含一个IO对象
4. 该IO对象是一个字节流传输对象
5. 服务器端必须明确的两件事:
    a. 服务器与多个客户端进行交互时,服务器必须明确当前是和哪个客户端交互
        可以使用服务器端的accept方法获取请求的客户端对象
    b. 服务器端是没有流对象的,它时通过获取请求的客户端对象Socket
        使用获取到达Socket对象中的IO流与该对象进行通信
            使用该对象的字节输入流读取客户端发送的数据
            使用该对象的字节输出流给客户端回数据
  1. Socket/ServerSocket
1. 表示客户端的类:Socket
2. 表示服务器端的类:ServerSocket
3. Socket:
    a. 构造方法:
        Socket(String host, int port);//传入服务器端的IP地址和端口号
    b. 重要成员方法:
        OutputStream getOutputStream();//获取输出流对象
        InputStream getInputStream();//获取输入流对象
        void close();//关闭该套接字
    c. 使用方法:
        1. 传入服务器端IP和端口号,创建客户端Socket对象
        2. 获取客户端的输出流OutputSream对象
        3. 使用OutputStream对象的write方法,将数据发送给服务器端
        4. 获取客户端的输入流InputStream对象
        5. 使用InputStream对象的read方法,读取客户端发送的数据
        6. 关闭Socket,释放对象。
    d. 注释事项:
        1. 客户端服务器通信必须使用Socket对象中获取到的网络流对象,不能使用自己定义的流对象
        2. 必须服务器端先启动,否则抛出异常
4. ServerSocket:
    a. 构造方法:
        ServerSocket(int port);//在指定端口开启服务器端
    b. 重要成员方法:
        Socket accept();//获取请求的客户端对象
    c. 使用方法:
        1. 传入指定端口号,创建服务器端对象
        2. 使用服务器端对象的accept成员方法获取请求的客户端Socket对象
        3. 使用获取到的客户端Socket对象的getInputStream获取输入流对象
        4. 使用InputStream对象的read方法读取客户端发送的字节流数据
        5. 使用获取到的客户端Socket对象的getOutputStream获取输出流对象
        6. 使用OutputStream对象的write方法向客户端发送字节流数据
        7. 关闭获取到的Socket对象
        8. 关闭服务器对象ServerSocket
  1. TCP文件上传与下载
1. 原理:客户端读取本地的文件,把文件上传到服务器,服务器将上传的文件保存到服务器的硬盘上
2. 使用步骤:
    a. 客户端使用<本地字节输入流>,读取要上传的文件
    b. 客户端使用(网络字节输出流),将读取的文件上传到服务器
    c. 服务器使用(网络字节输入流),读取客户端上传的文件
    d. 服务器端使用<本地字节输出流>,将读取到的文件保存到服务器硬盘上
    e. 服务器端使用(网络字节输出流),给客户端发送上传完毕消息
    f. 客户端使用(网络字节输出流),读取服务器端写回的数据
    g. 释放资源
3. 注意事项:
    由于上传文件的while循环条件while((len = fis.read(bytes)) != -1)
    因此,无法发送结束标识,使得服务器和客户端无法停止
    解决方案:
        当客户端上传完毕后,需要调用成员方法shutdownOutput
        用于禁用此套接字
        对于TCP套接字,任何之前写入的数据都将被发送,且跟一个TCP正常连接终止序列
4. 服务器端优化:多线程
    a. 将保存文件的方法写到线程run方法中
    b. 每次来一个客户端请求,开启一个线程
    c. 由于run方法没有声明抛出异常,所以子类实现同样不能抛出IOException,需要使用try/catch
  1. 模拟B/S版本
1. 由于浏览器/服务器版本接收的是浏览器请求,因此服务器端在处理请求是有所区别
2. 使用步骤:
    a. 浏览器端:
        输入指定ip地址和端口号,后接请求访问的文件路径
    b. 服务器端:
        1. 创建一个ServerSocket服务器对象,调用accept方法获取客户端请求的Socket对象
        2. 调用Socket对象获取InputStream网络字节输入对象
        3. 将获取到的网络字节输入流作为参数转化为字符缓冲输入流
            BufferedReader br = new BufferedReader(new InputStreamReader(网络字节输入流对象));
        4. 使用字符缓冲输入流对象成员方法readLine(),取出第一行包含请求内容地址的数据
        5. 提取出请求的文件路径,使用该路径构造本地文件字节输入流
        6. 回写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());
        7. while循环写回请求的网页给客户端
3. 服务器端优化:多线程
    1. 当没有开启多线程时,浏览器无法显示图片
    2. 浏览器解析服务器回写的html页面,页面如果有图片,那么浏览器就会单独的开启一个线程,读取服务器图片
    3. 因此就必须让服务已知处于监听状态<while(true)>,客户端请求一次,服务器开启一个线程回写一次
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值