`

Socket实战之七 使用Socket通信传输文件

    博客分类:
  • J2SE
阅读更多
http://blog.csdn.net/kongxx/article/details/7319410
前面几篇文章介绍了使用Java的Socket编程和NIO包在Socket中的应用,这篇文章说说怎样利用Socket编程来实现简单的文件传输。

这里由于前面一片文章介绍了NIO在Socket中的应用,所以这里在读写文件的时候也继续使用NIO包,所以代码看起来会比直接使用流的方式稍微复杂一点点。

下面的示例演示了客户端向服务器端发送一个文件,服务器作为响应给客户端会发一个文件。这里准备两个文件E:/test/server_send.log和E:/test/client.send.log文件,在测试完毕后在客户端和服务器相同目录下会多出两个文件E:/test/server_receive.log和E:/test/client.receive.log文件。

下面首先来看看Server类,主要关注其中的sendFile和receiveFile方法。

[java] view plaincopyprint?
package com.googlecode.garbagecan.test.socket.nio; 
 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.net.InetSocketAddress; 
import java.nio.ByteBuffer; 
import java.nio.channels.ClosedChannelException; 
import java.nio.channels.FileChannel; 
import java.nio.channels.SelectionKey; 
import java.nio.channels.Selector; 
import java.nio.channels.ServerSocketChannel; 
import java.nio.channels.SocketChannel; 
import java.util.Iterator; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
 
public class MyServer4 { 
 
    private final static Logger logger = Logger.getLogger(MyServer4.class.getName()); 
     
    public static void main(String[] args) { 
        Selector selector = null; 
        ServerSocketChannel serverSocketChannel = null; 
         
        try { 
            // Selector for incoming time requests 
            selector = Selector.open(); 
 
            // Create a new server socket and set to non blocking mode 
            serverSocketChannel = ServerSocketChannel.open(); 
            serverSocketChannel.configureBlocking(false); 
             
            // Bind the server socket to the local host and port 
            serverSocketChannel.socket().setReuseAddress(true); 
            serverSocketChannel.socket().bind(new InetSocketAddress(10000)); 
             
            // Register accepts on the server socket with the selector. This 
            // step tells the selector that the socket wants to be put on the 
            // ready list when accept operations occur, so allowing multiplexed 
            // non-blocking I/O to take place. 
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 
     
            // Here's where everything happens. The select method will 
            // return when any operations registered above have occurred, the 
            // thread has been interrupted, etc. 
            while (selector.select() > 0) { 
                // Someone is ready for I/O, get the ready keys 
                Iterator<SelectionKey> it = selector.selectedKeys().iterator(); 
     
                // Walk through the ready keys collection and process date requests. 
                while (it.hasNext()) { 
                    SelectionKey readyKey = it.next(); 
                    it.remove(); 
                     
                    // The key indexes into the selector so you 
                    // can retrieve the socket that's ready for I/O 
                    doit((ServerSocketChannel) readyKey.channel()); 
                } 
            } 
        } catch (ClosedChannelException ex) { 
            logger.log(Level.SEVERE, null, ex); 
        } catch (IOException ex) { 
            logger.log(Level.SEVERE, null, ex); 
        } finally { 
            try { 
                selector.close(); 
            } catch(Exception ex) {} 
            try { 
                serverSocketChannel.close(); 
            } catch(Exception ex) {} 
        } 
    } 
 
    private static void doit(final ServerSocketChannel serverSocketChannel) throws IOException { 
        SocketChannel socketChannel = null; 
        try { 
            socketChannel = serverSocketChannel.accept(); 
             
            receiveFile(socketChannel, new File("E:/test/server_receive.log")); 
            sendFile(socketChannel, new File("E:/test/server_send.log")); 
        } finally { 
            try { 
                socketChannel.close(); 
            } catch(Exception ex) {} 
        } 
         
    } 
     
    private static void receiveFile(SocketChannel socketChannel, File file) throws IOException { 
        FileOutputStream fos = null; 
        FileChannel channel = null; 
         
        try { 
            fos = new FileOutputStream(file); 
            channel = fos.getChannel(); 
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 
 
            int size = 0; 
            while ((size = socketChannel.read(buffer)) != -1) { 
                buffer.flip(); 
                if (size > 0) { 
                    buffer.limit(size); 
                    channel.write(buffer); 
                    buffer.clear(); 
                } 
            } 
        } finally { 
            try { 
                channel.close(); 
            } catch(Exception ex) {} 
            try { 
                fos.close(); 
            } catch(Exception ex) {} 
        } 
    } 
 
    private static void sendFile(SocketChannel socketChannel, File file) throws IOException { 
        FileInputStream fis = null; 
        FileChannel channel = null; 
        try { 
            fis = new FileInputStream(file); 
            channel = fis.getChannel(); 
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 
            int size = 0; 
            while ((size = channel.read(buffer)) != -1) { 
                buffer.rewind(); 
                buffer.limit(size); 
                socketChannel.write(buffer); 
                buffer.clear(); 
            } 
            socketChannel.socket().shutdownOutput(); 
        } finally { 
            try { 
                channel.close(); 
            } catch(Exception ex) {} 
            try { 
                fis.close(); 
            } catch(Exception ex) {} 
        } 
    } 

下面是Client程序代码,也主要关注sendFile和receiveFile方法
[java] view plaincopyprint?
package com.googlecode.garbagecan.test.socket.nio; 
 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.net.InetSocketAddress; 
import java.net.SocketAddress; 
import java.nio.ByteBuffer; 
import java.nio.channels.FileChannel; 
import java.nio.channels.SocketChannel; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
 
public class MyClient4 { 
 
    private final static Logger logger = Logger.getLogger(MyClient4.class.getName()); 
     
    public static void main(String[] args) throws Exception { 
        new Thread(new MyRunnable()).start(); 
    } 
     
    private static final class MyRunnable implements Runnable { 
        public void run() { 
            SocketChannel socketChannel = null; 
            try { 
                socketChannel = SocketChannel.open(); 
                SocketAddress socketAddress = new InetSocketAddress("localhost", 10000); 
                socketChannel.connect(socketAddress); 
 
                sendFile(socketChannel, new File("E:/test/client_send.log")); 
                receiveFile(socketChannel, new File("E:/test/client_receive.log")); 
            } catch (Exception ex) { 
                logger.log(Level.SEVERE, null, ex); 
            } finally { 
                try { 
                    socketChannel.close(); 
                } catch(Exception ex) {} 
            } 
        } 
 
        private void sendFile(SocketChannel socketChannel, File file) throws IOException { 
            FileInputStream fis = null; 
            FileChannel channel = null; 
            try { 
                fis = new FileInputStream(file); 
                channel = fis.getChannel(); 
                ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 
                int size = 0; 
                while ((size = channel.read(buffer)) != -1) { 
                    buffer.rewind(); 
                    buffer.limit(size); 
                    socketChannel.write(buffer); 
                    buffer.clear(); 
                } 
                socketChannel.socket().shutdownOutput(); 
            } finally { 
                try { 
                    channel.close(); 
                } catch(Exception ex) {} 
                try { 
                    fis.close(); 
                } catch(Exception ex) {} 
            } 
        } 
 
        private void receiveFile(SocketChannel socketChannel, File file) throws IOException { 
            FileOutputStream fos = null; 
            FileChannel channel = null; 
             
            try { 
                fos = new FileOutputStream(file); 
                channel = fos.getChannel(); 
                ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 
 
                int size = 0; 
                while ((size = socketChannel.read(buffer)) != -1) { 
                    buffer.flip(); 
                    if (size > 0) { 
                        buffer.limit(size); 
                        channel.write(buffer); 
                        buffer.clear(); 
                    } 
                } 
            } finally { 
                try { 
                    channel.close(); 
                } catch(Exception ex) {} 
                try { 
                    fos.close(); 
                } catch(Exception ex) {} 
            } 
        } 
    } 

首先运行MyServer4类启动监听,然后运行MyClient4类来向服务器发送文件以及接受服务器响应文件。运行完后,分别检查服务器和客户端接收到的文件
分享到:
评论

相关推荐

    TCP/Socket通信开发实战案例初始源码及重构代码

    一个简单的支持多个客户端链接的TCP/Socket...来自博客:c/c++开发,c++无可避免的TCP/Socket通信开发实战案例的初始源码 来自博客:c/c++开发,无可避免的代码重构实战(基于前文TCP/Socket通信开发案例)重构代码 ...

    Visual C++网络通信开发入门与编程实践.pdf(中文高清版)及源码

    第2篇介绍了7大类网络开发典型应用案例的实现,包括FTP客户端实现之一、 FTP客户端实现之二、网页浏览器、网络通信器、邮件接收和发送客户端之一、邮件接收和发送客户端之二、网络文件传输器、Q版聊天软件和聊天室。...

    Visual C++网络编程案例_part2.rar

    第2篇介绍了7大类网络开发典型应用案例的实现,包括FTP客户端实现之一、 FTP客户端实现之二、网页浏览器、网络通信器、邮件接收和发送客户端之一、邮件接收和发送客户端之二、网络文件传输器、Q版聊天软件和聊天室。...

    详解Android 基于TCP和UDP协议的Socket通信

    本来想讲一下基础的网络...而Socket通信中基于TCP/IP协议的通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求。而UDP则是提供无连接的数据报

    使用WebRTC实现实时通信

    本教程主要以WebRTC JavaScript API为例,使用WebRTC实现实时通信 1. 介绍WebRTC整体架构,WebRTC JavaScript API 2. 如何获取webcam摄像头音视频数据 3. WebRTC peer之间建联流程 4. 介绍WebRTC信令,使用socket.IO...

    Visual C++网络编程案例part1

    第2篇介绍了7大类网络开发典型应用案例的实现,包括FTP客户端实现之一、 FTP客户端实现之二、网页浏览器、网络通信器、邮件接收和发送客户端之一、邮件接收和发送客户端之二、网络文件传输器、Q版聊天软件和聊天室。...

    JAVA实战项目源码-计算机毕业设计java专业-项目源码-项目说明介绍-基于JAVA的网络通讯系统设计与实现(论文+系统)

    一般来说,聊天工具大多数由客户端程序和服务器程序,外加服务器端用于存放客户数据的数据库组成,本系统采用客户机/服务器架构模式,通过Java提供的Socket类来连接客户机和服务器并使客户机和服务器之间相互通信,...

    亮剑.NET深入体验与实战精要3

    10.2 异步Socket通信——实现MSN机器人 390 10.2.1 机器人服务端 390 10.2.2 客户端实现步骤 395 10.3 基于TCP协议的客户端和服务端 398 10.3.1 TcpListener 实现网络服务端 398 10.3.2 TcpClient实现网络客户端 399...

    Java高级程序设计实战教程第五章-Java序列化机制.pptx

    5.2.3 序列化的几种方式 在Java中socket传输数据时,数据类型往往比较难选择。可能要考虑带宽、跨语言、版本的兼容等问题。比较常见的做法有两种: 一是把对象包装成JSON字符串传输, 二是采用Java对象的序列化和反...

    Vue+Java 通过websocket实现服务器与客户端双向通信操作

    主要介绍了Vue+Java 通过websocket实现服务器与客户端双向通信操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

    老男孩python 四期

    ※分别开发服务器端和客户端,通过Socket模块实现网络通信,模拟实现FTP主要的文件下载、上传功能、实现多用户并发在线使用。 第六天 1、 项目实战三、开发运维审计服务器,实现公司全网用户操作审计需求 ※开发一个...

    亮剑.NET深入体验与实战精要2

    10.2 异步Socket通信——实现MSN机器人 390 10.2.1 机器人服务端 390 10.2.2 客户端实现步骤 395 10.3 基于TCP协议的客户端和服务端 398 10.3.1 TcpListener 实现网络服务端 398 10.3.2 TcpClient实现网络客户端 399...

    实战SSL加密

    SSL在客户和服务器之间建立一条加密通道,确保所传输的数据不被非法窃取,SSL安全加密机制功能是依靠使用数字证书来实现的。本文以Windows Server 2003(简称Windows 2003)系统为例,介绍如何在IIS6服务器中应用SSL...

    Java聊天应用程序 - 创建一个基本的即时聊天应用

    我们将使用Java的Socket编程来实现服务器端和客户端之间的通信,并使用Swing库来创建简单的用户界面。让我们一步一步地完成这个项目。 1. 项目概述 聊天应用程序将允许多个客户端通过服务器进行通信。每个客户端都...

    Linux高性能服务器编程

    1.5.2 ARP高速缓存的查看和修改 1.5.3 使用tcpdump观察ARP通信过程 1.6 DNS工作原理 1.6.1 DNS查询和应答报文详解 1.6.2 Linux下访问DNS服务 1.6.3 使用tcpdump观察DNS通信过程 1.7 socket和TCPIP协议族的...

    寒江独钓-Windows内核安全编程(高清完整版).part7

    9.3.2 在用户态通过DLL使用通信端口的范例 290 9.4 Minifilter的安装与加载 292 9.4.1 安装Minifilter的INF文件 293 9.4.2 启动安装完成的Minifilter 294 本章的示例代码 295 练习题 295 第10章 网络传输层过滤 296 ...

    netty-server中采用的分包拆包源码,java开发用于实战项目

    @Component public class RabbitmqConfig { private final static String message = "web.socket.message";...完整代码,下载有详细说明,使用于长报文通讯,将报文长度截取一定字节发送,便于网速传输中丢包

Global site tag (gtag.js) - Google Analytics