Java网络编程 ---- TCP 网络通信编程(二)

简介: Java网络编程 ---- TCP 网络通信编程(二)

6. 应用案例 4 文件上传

  1. 编写一个服务端,和一个客户端
  2. 服务器端在8888端口监听
  3. 客户端连接到服务端,发送一张图片 e:\bg.jpg

  4. 服务器端接收到客户端发送的图片,保存到src下,发送"收到图片”再退出
  5. 客户端接收到服务端发送的“收到图片”,再退出
  6. 该程序要求使用StreamUtils.java,我们直接使用
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
 * 此类用于演示关于流的读写方法
 *
 */
public class StreamUtils {
  /**
   * 功能:将输入流转换成byte[], 即可以把文件的内容读入到byte[]
   * @param is
   * @return
   * @throws Exception
   */
  public static byte[] streamToByteArray(InputStream is) throws Exception{
    ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象
    byte[] b = new byte[1024];//字节数组
    int len;
    while((len=is.read(b))!=-1){//循环读取
      bos.write(b, 0, len);//把读取到的数据,写入bos  
    }
    byte[] array = bos.toByteArray();//然后将bos 转成字节数组
    bos.close();
    return array;
  }
  /**
   * 功能:将InputStream转换成String
   * @param is
   * @return
   * @throws Exception
   */
  public static String streamToString(InputStream is) throws Exception{
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder builder= new StringBuilder();
    String line;
    while((line=reader.readLine())!=null){
      builder.append(line+"\r\n");
    }
    return builder.toString();
  }
}

TCPFileUploadServer.java

TCPFileUploadClient.java

6.1 创建服务器

package java学习.网络编程.TCP;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPFileUploadServer {
    public static void main(String[] args) throws IOException {
//        服务器在8888端口监听
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务器在8888端口监听");
//        等待连接
        Socket socket = serverSocket.accept();
        System.out.println( "服务端 socket=" + socket.getClass() );
    }
}

6.2 客户端读取文件上传文件

package java学习.网络编程.TCP;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPFileUploadClient {
    public static void main(String[] args) throws Exception {
//        连接服务端的8888端口
        Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
//        文件的路径
        String filePath = "e:\\bg.jpg";
//        输入流,读取图片
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
//        调用StreamUtils.streamToByteArray读取图片,获取二进制数组
        byte[] bytes = StreamUtils.streamToByteArray(bis);
//        通过 socket 获取到输出流, 将 bytes 数据发送给服务端
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        bos.write(bytes);//将文件对应的字节数组的内容,写入到数据通道
        socket.shutdownOutput();//设置写入数据的结束标记
//        关闭流
        bos.close();
        bis.close();
        socket.close();
    }
}

6.3 服务端读取流中的文件存放在src下

package java学习.网络编程.TCP;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPFileUploadServer {
    public static void main(String[] args) throws Exception {
//        服务器在8888端口监听
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务器在8888端口监听");
//        等待连接
        Socket socket = serverSocket.accept();
        System.out.println( "服务端 socket=" + socket.getClass() );
//        输入流,读取流中数据
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
//        调用StreamUtils.streamToByteArray将输入流中的数据读到数组中
        byte[] bytes = StreamUtils.streamToByteArray(bis);
//        将得到 bytes 数组,写入到指定的路径,就得到一个文件了
//        路径
        String filePath = "src\\bg.jpg";
//        输出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
        bos.write(bytes);
//        关闭
        bos.close();
        bis.close();
        socket.close();
        serverSocket.close();
    }
}

6.4 服务端回复信息

package java学习.网络编程.TCP;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPFileUploadServer {
    public static void main(String[] args) throws Exception {
//        服务器在8888端口监听
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务器在8888端口监听");
//        等待连接
        Socket socket = serverSocket.accept();
        System.out.println( "服务端 socket=" + socket.getClass() );
//        输入流,读取流中数据
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
//        调用StreamUtils.streamToByteArray将输入流中的数据读到数组中
        byte[] bytes = StreamUtils.streamToByteArray(bis);
//        将得到 bytes 数组,写入到指定的路径,就得到一个文件了
//        路径
        String filePath = "src\\bg.jpg";
//        输出流
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
        bos.write(bytes);
//        回复信息
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("收到图片");
        bw.flush();//把内容刷新到数据通道
//        客户端以字节流读取信息,可以设置如下结束标记
        socket.shutdownOutput();//设置写入结束标记
//        关闭
        bw.close();
        bos.close();
        bis.close();
        socket.close();
        serverSocket.close();
    }
}

6.5 服务端接收回复信息

package java学习.网络编程.TCP;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPFileUploadClient {
    public static void main(String[] args) throws Exception {
//        连接服务端的8888端口
        Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
//        文件的路径
        String filePath = "e:\\bg.jpg";
//        输入流,读取图片
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
//        调用StreamUtils.streamToByteArray读取图片,获取二进制数组
        byte[] bytes = StreamUtils.streamToByteArray(bis);
//        通过 socket 获取到输出流, 将 bytes 数据发送给服务端
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        bos.write(bytes);//将文件对应的字节数组的内容,写入到数据通道
        socket.shutdownOutput();//设置写入数据的结束标记
//        接收服务端回复的信息
        InputStream inputStream = socket.getInputStream();
//        使用 StreamUtils 的方法,直接将 inputStream 读取到的内容 转成字符串
        String s = StreamUtils.streamToString(inputStream);
        System.out.println(s);
//        关闭流
        inputStream.close();
        bos.close();
        bis.close();
        socket.close();
    }
}

效果

7. netstat 指令

  1. netstat -an 可以查看当前主机网络情况,包括端口监听情况和网络连接情况
  2. netstat -an | more可以分页显示 空格下一页
  3. 要求在dos控制台下执行 win+r

说明:

(1) Listening表示某个端口在监听

(2)如果有一个外部程序(客户端)连接到该端口,就会显示一条连接信息.

(3)可以输入ctrl +c退出指令

netstat -a
netstat -an | more

netstat -an

可以查看哪些应用在监听端口(要用管理员的身份打开命令窗口)

8. TCP 网络通讯不为人知的秘密

当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是TCP/IP来分配的,是不确定的,是随机的.



相关文章
|
20天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
20天前
|
程序员 开发者 Python
Python网络编程基础(Socket编程) 错误处理和异常处理的最佳实践
【4月更文挑战第11天】在网络编程中,错误处理和异常管理不仅是为了程序的健壮性,也是为了提供清晰的用户反馈以及优雅的故障恢复。在前面的章节中,我们讨论了如何使用`try-except`语句来处理网络错误。现在,我们将深入探讨错误处理和异常处理的最佳实践。
|
22天前
|
存储 Python
Python网络编程基础(Socket编程)UDP客户端编程
【4月更文挑战第9天】在UDP通信中,客户端负责发送数据到服务器,并接收来自服务器的响应。与服务器不同,客户端通常不需要绑定到特定的地址和端口,因为它可以临时使用任何可用的端口来发送数据。下面,我们将详细讲解UDP客户端编程的基本步骤。
|
7天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
11天前
|
监控 Java 开发者
深入理解 Java 网络编程和 NIO
【4月更文挑战第19天】Java网络编程基于Socket,但NIO(非阻塞I/O)提升了效率和性能。NIO特点是非阻塞模式、选择器机制和缓冲区,适合高并发场景。使用NIO涉及通道、选择器和事件处理,优点是高并发、资源利用率和可扩展性,但复杂度、错误处理和性能调优是挑战。开发者应根据需求选择是否使用NIO,并深入理解其原理。
|
14天前
|
网络协议 Java API
深度剖析:Java网络编程中的TCP/IP与HTTP协议实践
【4月更文挑战第17天】Java网络编程重在TCP/IP和HTTP协议的应用。TCP提供可靠数据传输,通过Socket和ServerSocket实现;HTTP用于Web服务,常借助HttpURLConnection或Apache HttpClient。两者结合,构成网络服务基础。Java有多种高级API和框架(如Netty、Spring Boot)简化开发,助力高效、高并发的网络通信。
|
16天前
|
SQL 安全 Java
Java安全编程:防范网络攻击与漏洞
【4月更文挑战第15天】本文强调了Java安全编程的重要性,包括提高系统安全性、降低维护成本和提升用户体验。针对网络攻击和漏洞,提出了防范措施:使用PreparedStatement防SQL注入,过滤和转义用户输入抵御XSS攻击,添加令牌对抗CSRF,限制文件上传类型和大小以防止恶意文件,避免原生序列化并确保数据完整性。及时更新和修复漏洞是关键。程序员应遵循安全编程规范,保障系统安全。
|
19天前
|
网络协议 Java API
Python网络编程基础(Socket编程)Twisted框架简介
【4月更文挑战第12天】在网络编程的实践中,除了使用基本的Socket API之外,还有许多高级的网络编程库可以帮助我们更高效地构建复杂和健壮的网络应用。这些库通常提供了异步IO、事件驱动、协议实现等高级功能,使得开发者能够专注于业务逻辑的实现,而不用过多关注底层的网络细节。
|
19天前
|
分布式计算 监控 Hadoop
Hadoop【基础知识 02】【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
【4月更文挑战第3天】Hadoop【基础知识 02】【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
56 0
|
22天前
|
网络协议 安全 网络性能优化