`

如何把Socket作为平台 发送和接收文件

阅读更多

这是一个简单的包含发送端和接收端的例子。发送端向接收端发送文件名和文件内容,接收端将收到的文件保存在磁盘上。接收端可以同时接收多个发送端传来的文件,但没有处理文件同名的情况。

这个例子中设计了一个简单的协议。发送的内容是这样的:

文件名长度(4字节)—文件名—文件内容长度(4字节)—文件内容。

接收端也按照这个结构进行解析。建议先看 Client 类,再看 Server 类。

view plaincopy to clipboardprint?
import java.io.*;   
import java.net.ServerSocket;   
import java.net.Socket;   
    
/**  
 * 简单的文件发送与接收示例  
 */  
public class FileTrasmission {   
    
    //程序入口   
    public static void main(String[] args) throws Exception {   
        int port = 7788;   
        new Server(port, "c:\\save\\").start();   
        new Client().sendFile("127.0.0.1", port, "c:\\迷失在康熙末年.txt");   
    }   
}   
    
/**  
 * 接收端。可同时接收多个发送端发来的文件。但如果发来的文件是同名的话那就乱了。  
 */  
class Server {   
    
    private int listenPort;   
    
    private String savePath;   
    
    /**  
     * 构造方法  
     *  
     * @param listenPort 侦听端口  
     * @param savePath   接收的文件要保存的路径  
     *  
     * @throws IOException 如果创建保存路径失败  
     */  
    Server(int listenPort, String savePath) throws IOException {   
        this.listenPort = listenPort;   
        this.savePath = savePath;   
    
        File file = new File(savePath);   
        if (!file.exists() && !file.mkdirs()) {   
            throw new IOException("无法创建文件夹 " + savePath);   
        }   
    }   
    
    // 开始侦听   
    public void start() {   
        new ListenThread().start();   
    }   
    
    // 网上抄来的,将字节转成 int。b 长度不得小于 4,且只会取前 4 位。   
    public static int b2i(byte[] b) {   
        int value = 0;   
        for (int i = 0; i < 4; i++) {   
            int shift = (4 - 1 - i) * 8;   
            value += (b[i] & 0x000000FF) << shift;   
        }   
        return value;   
    }   
    
    
    /**  
     * 侦听线程  
     */  
    private class ListenThread extends Thread {   
    
        @Override  
        public void run() {   
            try {   
                ServerSocket server = new ServerSocket(listenPort);   
    
                // 开始循环   
                while (true) {   
                    Socket socket = server.accept();   
                    new HandleThread(socket).start();   
                }   
            } catch (IOException e) {   
                e.printStackTrace();   
            }   
        }   
    }   
    
    /**  
     * 读取流并保存文件的线程  
     */  
    private class HandleThread extends Thread {   
    
        private Socket socket;   
    
        private HandleThread(Socket socket) {   
            this.socket = socket;   
        }   
    
        @Override  
        public void run() {   
            try {   
                InputStream is = socket.getInputStream();   
                readAndSave(is);   
            } catch (IOException e) {   
                e.printStackTrace();   
            } finally {   
                try {   
                    socket.close();   
                } catch (IOException e) {   
                    // nothing to do   
                }   
            }   
        }   
    
        // 从流中读取内容并保存   
        private void readAndSave(InputStream is) throws IOException {   
            String filename = getFileName(is);   
            int file_len = readInteger(is);   
            System.out.println("接收文件:" + filename + ",长度:" + file_len);   
    
            readAndSave0(is, savePath + filename, file_len);   
    
            System.out.println("文件保存成功(" + file_len + "字节)。");   
        }   
    
        private void readAndSave0(InputStream is, String path, int file_len) throws IOException {   
            FileOutputStream os = getFileOS(path);   
            readAndWrite(is, os, file_len);   
            os.close();   
        }   
    
        // 边读边写,直到读取 size 个字节   
        private void readAndWrite(InputStream is, FileOutputStream os, int size) throws IOException {   
            byte[] buffer = new byte[4096];   
            int count = 0;   
            while (count < size) {   
                int n = is.read(buffer);   
                // 这里没有考虑 n = -1 的情况   
                os.write(buffer, 0, n);   
                count += n;   
            }   
        }   
    
        // 读取文件名   
        private String getFileName(InputStream is) throws IOException {   
            int name_len = readInteger(is);   
            byte[] result = new byte[name_len];   
            is.read(result);   
            return new String(result);   
        }   
    
        // 读取一个数字   
        private int readInteger(InputStream is) throws IOException {   
            byte[] bytes = new byte[4];   
            is.read(bytes);   
            return b2i(bytes);   
        }   
    
        // 创建文件并返回输出流   
        private FileOutputStream getFileOS(String path) throws IOException {   
            File file = new File(path);   
            if (!file.exists()) {   
                file.createNewFile();   
            }   
    
            return new FileOutputStream(file);   
        }   
    }   
}   
    
/**  
 * 发送端  
 */  
class Client {   
    
    // 网上抄来的,将 int 转成字节   
    public static byte[] i2b(int i) {   
        return new byte[]{   
                (byte) ((i >> 24) & 0xFF),   
                (byte) ((i >> 16) & 0xFF),   
                (byte) ((i >> 8) & 0xFF),   
                (byte) (i & 0xFF)   
        };   
    }   
    
    /**  
     * 发送文件。文件大小不能大于 {@link Integer#MAX_VALUE}  
     *  
     * @param hostname 接收端主机名或 IP 地址  
     * @param port     接收端端口号  
     * @param filepath 文件路径  
     *  
     * @throws IOException 如果读取文件或发送失败  
     */  
    public void sendFile(String hostname, int port, String filepath) throws IOException {   
        File file = new File(filepath);   
        FileInputStream is = new FileInputStream(filepath);   
    
        Socket socket = new Socket(hostname, port);   
        OutputStream os = socket.getOutputStream();   
    
        try {   
            int length = (int) file.length();   
            System.out.println("发送文件:" + file.getName() + ",长度:" + length);   
    
            // 发送文件名和文件内容   
            writeFileName(file, os);   
            writeFileContent(is, os, length);   
        } finally {   
            os.close();   
            is.close();   
        }   
    }   
    
    // 输出文件内容   
    private void writeFileContent(InputStream is, OutputStream os, int length) throws IOException {   
        // 输出文件长度   
        os.write(i2b(length));   
    
        // 输出文件内容   
        byte[] buffer = new byte[4096];   
        int size;   
        while ((size = is.read(buffer)) != -1) {   
            os.write(buffer, 0, size);   
        }   
    }   
    
    // 输出文件名   
    private void writeFileName(File file, OutputStream os) throws IOException {   
        byte[] fn_bytes = file.getName().getBytes();   
    
        os.write(i2b(fn_bytes.length));         // 输出文件名长度   
        os.write(fn_bytes);    // 输出文件名   
    }   
}  

 

分享到:
评论

相关推荐

    C# Socket 发送接收文件,消息

    C#作为.NET框架的主要编程语言,提供了强大的Socket类库来处理网络通信,包括文件的发送和接收以及消息传递。本主题将深入探讨如何使用C#的Socket进行文件传输和消息交互。 首先,Socket是网络通信的基本构建块,它...

    C# socket发送(接收)文件

    本文将详细讲解如何使用C#的Socket类进行文件的发送与接收,主要围绕`SingleSendForm`和`MultiSendForm`两个程序实例展开。 首先,Socket在C#中是System.Net.Sockets命名空间下的类,它提供了在网络中进行数据传输...

    C#用Socket发送和接收文件的源代码

    C#作为.NET框架下的主要编程语言,提供了丰富的类库来支持Socket编程,使得开发者能够轻松地构建网络应用,包括发送和接收文件。在这个场景中,我们有两个核心文件:ReceiveFiles.zip和SendFiles.zip,它们分别包含...

    c#使用一个socket同时发送字符串和文件

    本文将深入探讨如何使用一个Socket实例同时发送字符串和文件。在实际应用中,这通常是通过结合使用流(Stream)和序列化来实现的。 首先,我们需要理解Socket的工作原理。Socket是基于TCP/IP协议栈的,它提供了套接...

    socket服务和客户端测试XML文件接收和发送

    在本案例中,XML文件会被序列化为字节流,然后通过Socket发送。接收端则反序列化接收到的字节流回XML文档。 4. **客户端**:客户端是主动发起连接请求的程序。在C#中,客户端首先创建一个Socket实例,然后使用`...

    VB使用Socket控件发送接收文件的例子

    本示例将讲解如何使用Socket控件在VB中发送和接收文件。 首先,我们需要了解Socket控件的主要属性和方法。在VB中,Socket控件通常称为Winsock控件,它有以下几个关键属性: 1. **LocalHost**: 定义本地主机名或IP...

    Socket传输大文件(发送与接收源码)

    Socket编程在IT行业中是网络通信的基础,特别是在C#这样的多平台开发环境中,Socket提供了一种...这个"Socket传输大文件(发送与接收源码)"项目,就是一个很好的实践平台,可以帮助开发者深入学习和掌握这些关键技能。

    c# socket 发送 接受 文件

    在IT行业中,网络通信是至关重要的一个领域,而C#作为一种强大的编程语言,提供了丰富的库支持来实现网络通信,特别是通过Socket进行文件的发送和接收。本篇文章将深入探讨如何利用C#的Socket类库来实现跨机器的文件...

    利用socket连续发送与连续接收数据

    在IT领域,网络编程是不可或缺的一部分,而Socket编程则是实现网络...连续发送和接收数据的场景在许多应用中都很常见,比如文件传输、在线聊天等。通过理解和掌握Socket编程,开发者可以构建出高效且可靠的网络应用。

    socket发送接收文件

    在"socket发送接收文件"的过程中,通常采用客户端-服务器模型。服务器端创建一个监听Socket,等待客户端的连接请求。一旦客户端连接成功,双方就可以通过已建立的连接进行数据交换。数据可以是以字节流形式的文件...

    C#使用Socket实现发送和接收图片的方法

    本示例中,我们将探讨如何使用C#的Socket类来实现发送和接收图片的功能。 首先,我们创建一个服务器端,其主要任务是监听客户端的连接请求,并将图片文件发送给客户端。在`Main`方法中,我们执行以下步骤: 1. **...

    C# Socket通信(winform) 异步发送消息,服务端客户端通信,可以发送消息和文件并进行接收

    C# Socket通信(winform) 异步发送消息,服务端客户端通信,可以发送消息和文件并进行接收,代码注释详细 C# Socket通信(winform) 异步发送消息,服务端客户端通信,可以发送消息和文件并进行接收,代码注释详细 ...

    C#发送和接收文件示例

    在这个示例中,"SendFileTestSender"可能是一个客户端程序,它负责将文件分割成多个数据块,并通过Socket发送到服务器端。分块传输是为了避免一次性发送大文件导致的内存压力和网络阻塞。每个数据块可以根据需要设定...

    C# 使用Socket发送和接收TCP数据

    本篇文章将深入探讨如何在C#中使用Socket类来实现TCP数据的发送和接收。 TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议,它确保了数据包的顺序传输和错误校验。在C#中,Socket类是.NET ...

    java基于socket的文件发送与接收,有界面,有进度条

    当用户点击“发送”按钮时,文件选择的结果会被传递给后台处理线程,该线程负责文件的读取和通过Socket发送。 文件的传输通常采用分块读写的方式,因为一次性读取整个大文件可能会导致内存溢出。可以通过设置合适的...

    Socket 通信及其发送文件

    三、Socket发送文件 1. 文件读取:在发送文件前,我们需要将文件内容读取到内存中。C#提供了FileStream类用于读写文件,可以使用Read方法按字节读取文件内容。 2. 数据分块:由于Socket一次只能发送有限大小的数据...

    socket编程c语言发送文件

    Socket编程是计算机网络通信的核心...通过阅读和理解这些代码,你可以深入了解如何使用C语言进行socket编程,以及如何结合多线程和队列缓冲技术来发送文件。这是一项基础但关键的技能,对于开发网络应用程序非常有用。

    socket文件发送与接收

    ### Socket文件发送与接收知识点详解 #### 一、Socket编程基础 在计算机网络通信中,套接字(Socket)是一种用于实现不同计算机间进程通信的协议。它为应用程序提供了访问低层传输协议(如TCP/IP)的方法。通过...

    socket发送小工具

    Socket发送小工具是一款基于C#编程语言开发的实用程序,主要功能是模拟Socket通信,用于测试网络连接和数据传输。在IT行业中,Socket编程是一种基础且重要的技术,它允许应用程序通过网络进行通信,就像两个应用程序...

Global site tag (gtag.js) - Google Analytics