Java系列笔记第七章:Java基础网络编程

第七章 : Java基础网络编程

1. 网络编程入门

1.1 软件结构

C/S结构与B/S结构。

1.2 网络通信协议

专注于研究传输层:

  • TCP 传输控制协议。
  • UDP 用户数据报协议。

1.3 网络编程三要素

  1. 协议
  2. IP地址
  3. 端口号

2. TCP通信程序

2.1 概述

Java中,提供了两个类用于实现TCP通信程序。

  • 客户端 java.net.Socket, 创建Socket对象。
  • 服务端 java.net.ServerSocket,创建ServerSocket对象。

客户端与服务端之间的逻辑连接包含一个IO对象,本质上是字节流对象。

2.2 TCP客户端代码实现

构造方法:

  • Socket(String host, int port);

成员方法:

  • OutputStream getOutputStream() 返回套接字的输出流。
  • InputStream getInputStream() 返回套接字的输入流。
  • close() 关闭套接字。

使用步骤:

  1. 创建套接字对象,绑定服务器IP和端口。
  2. 使用getOutputStream()获取套接字输出流对象。
  3. 使用套接字输出流对象的write()方法给服务器发消息。
  4. 使用getInputStream()获取套接字输入流对象。
  5. 使用套接字输入流对象的read()方法读取服务器回复的消息。
  6. 使用close()关闭socket对象。

提示:

创建套接字对象时,如果服务器没有启动,就会抛出异常java.net.ConnectException

package SocketDemo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class TCPCLient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 9999);
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("客户端说: 爷给你发数据了。".getBytes());
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int len = inputStream.read(bytes);
        System.out.println(new String(bytes, 0, len));
        socket.close();
    }
}

2.3 TCP服务端代码实现

构造方法:

  • ServerSocket(int port); 绑定服务器本机端口号。

成员方法:

  • Socket accept() 监听并获取到客户端发送来的套接字。
  • OutputStream getOutputStream() 返回套接字的输出流。
  • InputStream getInputStream() 返回套接字的输入流。
  • close() 关闭套接字。

使用步骤:

  1. 创建服务端套接字对象,绑定服务器本机端口号。
  2. 使用accept()方法监听并获取客户端套接字。
  3. 使用客户端套接字的getInputStream()方法获取字节输入流对象。
  4. 使用InputStream对象的read()方法获取客户端发来的消息。
  5. 使用客户端套接字的getOutputStream()对象获取字节输出流对象。
  6. 使用OutputStream对象的write()方法给客户端发消息。
  7. 关闭客户端套接字。
  8. 关闭服务端套接字。
package SocketDemo;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;

public class TCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket socket = new ServerSocket(9999);
        Socket clientSocket = socket.accept();
        InputStream inputStream = clientSocket.getInputStream();
        byte[] bytes = new byte[1024];
        int len = inputStream.read(bytes);
        System.out.println(new String(bytes,0,len));
        OutputStream outputStream = clientSocket.getOutputStream();
        outputStream.write("服务器说: 爷收到了".getBytes());
        clientSocket.close();
        socket.close();
    }
}

3. 文件上传示例

3.1 文件上传

3.2 文件上传的阻塞问题

read()方法如果没有输入可用,此方法将阻塞。

read方法并不能读取到文件的结束符,也就是-1,所以客户端和服务器都会进入阻塞状态。

解决方案:

发送文件的套接字主动关闭套接字输出流。

public void shutdownOutput()

禁用此套接字的输出流。对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。

4. 文件上传的多线程优化

4.1 文件名称

在服务端自定义文件名称。

4.2 服务端多线程监听并接收客户端的套接字

  1. 让服务器一直处于监听状态
  2. 有客户端上传文件,就开启一个新线程。
    new Thread(new Runnable() {
        @Override
        public void run() {
            //上传文件的代码
        }
    }).start();
    
  3. 因为run方法没有抛出异常,所以异常都需要用try-catch进行处理。

5. 模拟B/S结构的服务端

注意:

浏览器如果检测到网页有图片,就会开新线程去访问图片,所以服务端需要写成多线程模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值