Java Socket TCP以字节数组方式,分片传输文件

需求:两端以TCP方式建立连接,分片传输文件;

思路:本端将大文件切片,并将文件名称、分片、文件大小、文件MD5、分片内容等信息,封装成一个对象,将对象转为字节数组,以字节流传输到对端;对端接收到字节数组后,转转为对象,再交给业务层处理数据;

接收线程:ReceiveTcpThread

package com.jzsg.ferry.thread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;


public class ReceiveTcpThread implements Runnable {

    /**
     * logger
     */
    private static final Logger logger = LoggerFactory.getLogger(ReceiveTcpThread.class);

    private final Socket s;

    public ByteArrayInputStream bis = null;


    public int num;

    public ReceiveTcpThread(Socket s) {
        this.s = s;
    }
    
    @SuppressWarnings("InfiniteLoopStatement")
    @Override
    public void run() {
        try {
            InputStream in = s.getInputStream();
            logger.info("接收线程已启动");
            DataInputStream dis = new DataInputStream(in);

            logger.info("接收线程已启动");
            while (true) {
                int length = dis.readInt();

                byte[] buf = new byte[length];
                int bufSize = 2048;
                int pos = 0;
                int read = 0;
                if (length < bufSize) {
                    read = dis.read(buf,pos,length);
                } else {
                    while(true) {
                        int can = dis.available();
                        if (can > bufSize) {
                            read = dis.read(buf,pos,bufSize);
                        } else {
                            read = dis.read(buf,pos,can);
                            break;
                        }
                        pos = pos + read;
                    }
                }
                //交给业务层处理buf数组
                logger.info("接收数据:" + Arrays.toString(buf));

            }
        } catch (IOException e) {
            logger.error("socket异常:" + e.getMessage());
        }
    }
  
}

SendTcpThread 发送线程: 

package thread;


import com.jzsg.common.pool.BussinessThreadPool;
import common.Converter;
import model.Student;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pool.FerryToolThreadPool;
import service.HandleDataService;
import util.PropertyUtil;

import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.concurrent.ConcurrentLinkedQueue;


public class SendTcpThread implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(SendTcpThread.class);

    public String destIp = PropertyUtil.getProperty("DEST_IP");

    public Socket socket;

    public OutputStream out = null;

    public DataOutputStream dos = null;

    protected volatile ConcurrentLinkedQueue<byte[]> dataQueue = new ConcurrentLinkedQueue<>();

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }

    @Override
    @SuppressWarnings("InfiniteLoopStatement")
    public void run() {
        try {
            int port = 9002;
            //建立客户端Socket
            InetSocketAddress endpoint = new InetSocketAddress(destIp , port);
            socket = new Socket();
            //连接服务器
            socket.connect(endpoint);
            setSocket(socket);
            out = socket.getOutputStream();
            //发送字节数组
            dos = new DataOutputStream(out);
            while (true) {
                byte[] data = dataQueue.poll();
                logger.info("dataQueue:" + dataQueue.size());
                if (null == data || data.length <= 0) {
                    //没有发送数据则等待
                    toWait(dataQueue, 0);
                } else {
                    logger.info("发送端的数据长度:" + data.length);
                    //发送字节数组长度
                    dos.writeInt(data.length);
                    dos.write(data);
                    dos.flush();
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (IOException e) {
            logger.error("socket连接异常", e);
            FerryToolManager.getInstance().closeSendThread();
        }
    }

}
ListenerThread 监听线程:
package thread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pool.FerryToolThreadPool;
import state.HandleData;
import util.PropertyUtil;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ListenerThread implements Runnable {
    /**
     * logger
     */
    private static final Logger logger = LoggerFactory.getLogger(ListenerThread.class);

    /**
     * serverSocket
     */
    private ServerSocket serverSocket = null;

    //暴露接口,给业务层实现及调用;
    private final HandleData handleData;

    public ListenerThread(HandleData handleData) {
        this.handleData = handleData;
    }

    @Override
    @SuppressWarnings("InfiniteLoopStatement")
    public void run() {
        try{
            int port = 9003;
            serverSocket = new ServerSocket(port);
            while(true){
                //获取客户端Socket
                Socket s = serverSocket.accept();
                ReceiveTcpThread receiveTcpThread = new ReceiveTcpThread(s, handleData);
                FerryToolManager.getInstance().add(receiveTcpThread);
                FerryToolThreadPool.execute(receiveTcpThread);
            }
        } catch (IOException e) {
            logger.info("监听线程启动异常",e);
        }
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以使用JavaSocket和InputStream/OutputStream类来实现TCP通信,具体实现方法如下: 1. 在服务器端,创建一个ServerSocket对象并指定端口号,等待客户端的连接。一旦有客户端连接,就会返回一个Socket对象。 2. 获取输入输出流。在服务器端,可以使用Socket对象获取InputStream和OutputStream类的实例,它们用于接收和发送数据。在客户端,也可以使用Socket对象获取输入输出流。 3. 接收和发送数据。在客户端,可以使用OutputStream类的write()方法向服务器端发送字节数组。在服务器端,可以使用InputStream类的read()方法接收客户端发送的字节数组,然后再使用OutputStream类的write()方法向客户端发送字节数组。 例子:服务器端代码 ```java ServerSocket serverSocket = new ServerSocket(8000); Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); byte[] data = new byte[1024]; int length = inputStream.read(data); outputStream.write(data, 0, length); ``` 客户端代码 ```java Socket socket = new Socket("localhost", 8000); OutputStream outputStream = socket.getOutputStream(); InputStream inputStream = socket.getInputStream(); byte[] message = "Hello, server!".getBytes(); outputStream.write(message); byte[] data = new byte[1024]; int length = inputStream.read(data); System.out.println(new String(data, 0, length)); ``` 关于你的问题,你可以将客户端发送的字节数组直接写入服务器的字节数组中,具体实现方式就是在服务器端使用InputStream类的read()方法获取客户端发送过来的字节数组,然后把它写入另一个字节数组中即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值