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

前面几篇文章介绍了使用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方法。

  1. package com.googlecode.garbagecan.test.socket.nio; 
  2.  
  3. import java.io.File; 
  4. import java.io.FileInputStream; 
  5. import java.io.FileOutputStream; 
  6. import java.io.IOException; 
  7. import java.net.InetSocketAddress; 
  8. import java.nio.ByteBuffer; 
  9. import java.nio.channels.ClosedChannelException; 
  10. import java.nio.channels.FileChannel; 
  11. import java.nio.channels.SelectionKey; 
  12. import java.nio.channels.Selector; 
  13. import java.nio.channels.ServerSocketChannel; 
  14. import java.nio.channels.SocketChannel; 
  15. import java.util.Iterator; 
  16. import java.util.logging.Level; 
  17. import java.util.logging.Logger; 
  18.  
  19. public class MyServer4 { 
  20.  
  21.     private final static Logger logger = Logger.getLogger(MyServer4.class.getName()); 
  22.      
  23.     public static void main(String[] args) { 
  24.         Selector selector = null
  25.         ServerSocketChannel serverSocketChannel = null
  26.          
  27.         try
  28.             // Selector for incoming time requests 
  29.             selector = Selector.open(); 
  30.  
  31.             // Create a new server socket and set to non blocking mode 
  32.             serverSocketChannel = ServerSocketChannel.open(); 
  33.             serverSocketChannel.configureBlocking(false); 
  34.              
  35.             // Bind the server socket to the local host and port 
  36.             serverSocketChannel.socket().setReuseAddress(true); 
  37.             serverSocketChannel.socket().bind(new InetSocketAddress(10000)); 
  38.              
  39.             // Register accepts on the server socket with the selector. This 
  40.             // step tells the selector that the socket wants to be put on the 
  41.             // ready list when accept operations occur, so allowing multiplexed 
  42.             // non-blocking I/O to take place. 
  43.             serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 
  44.      
  45.             // Here's where everything happens. The select method will 
  46.             // return when any operations registered above have occurred, the 
  47.             // thread has been interrupted, etc. 
  48.             while (selector.select() > 0) { 
  49.                 // Someone is ready for I/O, get the ready keys 
  50.                 Iterator<SelectionKey> it = selector.selectedKeys().iterator(); 
  51.      
  52.                 // Walk through the ready keys collection and process date requests. 
  53.                 while (it.hasNext()) { 
  54.                     SelectionKey readyKey = it.next(); 
  55.                     it.remove(); 
  56.                      
  57.                     // The key indexes into the selector so you 
  58.                     // can retrieve the socket that's ready for I/O 
  59.                     doit((ServerSocketChannel) readyKey.channel()); 
  60.                 } 
  61.             } 
  62.         } catch (ClosedChannelException ex) { 
  63.             logger.log(Level.SEVERE, null, ex); 
  64.         } catch (IOException ex) { 
  65.             logger.log(Level.SEVERE, null, ex); 
  66.         } finally
  67.             try
  68.                 selector.close(); 
  69.             } catch(Exception ex) {} 
  70.             try
  71.                 serverSocketChannel.close(); 
  72.             } catch(Exception ex) {} 
  73.         } 
  74.     } 
  75.  
  76.     private static void doit(final ServerSocketChannel serverSocketChannel) throws IOException { 
  77.         SocketChannel socketChannel = null
  78.         try
  79.             socketChannel = serverSocketChannel.accept(); 
  80.              
  81.             receiveFile(socketChannel, new File("E:/test/server_receive.log")); 
  82.             sendFile(socketChannel, new File("E:/test/server_send.log")); 
  83.         } finally
  84.             try
  85.                 socketChannel.close(); 
  86.             } catch(Exception ex) {} 
  87.         } 
  88.          
  89.     } 
  90.      
  91.     private static void receiveFile(SocketChannel socketChannel, File file) throws IOException { 
  92.         FileOutputStream fos = null
  93.         FileChannel channel = null
  94.          
  95.         try
  96.             fos = new FileOutputStream(file); 
  97.             channel = fos.getChannel(); 
  98.             ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 
  99.  
  100.             int size = 0
  101.             while ((size = socketChannel.read(buffer)) != -1) { 
  102.                 buffer.flip(); 
  103.                 if (size > 0) { 
  104.                     buffer.limit(size); 
  105.                     channel.write(buffer); 
  106.                     buffer.clear(); 
  107.                 } 
  108.             } 
  109.         } finally
  110.             try
  111.                 channel.close(); 
  112.             } catch(Exception ex) {} 
  113.             try
  114.                 fos.close(); 
  115.             } catch(Exception ex) {} 
  116.         } 
  117.     } 
  118.  
  119.     private static void sendFile(SocketChannel socketChannel, File file) throws IOException { 
  120.         FileInputStream fis = null
  121.         FileChannel channel = null
  122.         try
  123.             fis = new FileInputStream(file); 
  124.             channel = fis.getChannel(); 
  125.             ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 
  126.             int size = 0
  127.             while ((size = channel.read(buffer)) != -1) { 
  128.                 buffer.rewind(); 
  129.                 buffer.limit(size); 
  130.                 socketChannel.write(buffer); 
  131.                 buffer.clear(); 
  132.             } 
  133.             socketChannel.socket().shutdownOutput(); 
  134.         } finally
  135.             try
  136.                 channel.close(); 
  137.             } catch(Exception ex) {} 
  138.             try
  139.                 fis.close(); 
  140.             } catch(Exception ex) {} 
  141.         } 
  142.     } 
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方法

  1. package com.googlecode.garbagecan.test.socket.nio; 
  2.  
  3. import java.io.File; 
  4. import java.io.FileInputStream; 
  5. import java.io.FileOutputStream; 
  6. import java.io.IOException; 
  7. import java.net.InetSocketAddress; 
  8. import java.net.SocketAddress; 
  9. import java.nio.ByteBuffer; 
  10. import java.nio.channels.FileChannel; 
  11. import java.nio.channels.SocketChannel; 
  12. import java.util.logging.Level; 
  13. import java.util.logging.Logger; 
  14.  
  15. public class MyClient4 { 
  16.  
  17.     private final static Logger logger = Logger.getLogger(MyClient4.class.getName()); 
  18.      
  19.     public static void main(String[] args) throws Exception { 
  20.         new Thread(new MyRunnable()).start(); 
  21.     } 
  22.      
  23.     private static final class MyRunnable implements Runnable { 
  24.         public void run() { 
  25.             SocketChannel socketChannel = null
  26.             try
  27.                 socketChannel = SocketChannel.open(); 
  28.                 SocketAddress socketAddress = new InetSocketAddress("localhost", 10000); 
  29.                 socketChannel.connect(socketAddress); 
  30.  
  31.                 sendFile(socketChannel, new File("E:/test/client_send.log")); 
  32.                 receiveFile(socketChannel, new File("E:/test/client_receive.log")); 
  33.             } catch (Exception ex) { 
  34.                 logger.log(Level.SEVERE, null, ex); 
  35.             } finally
  36.                 try
  37.                     socketChannel.close(); 
  38.                 } catch(Exception ex) {} 
  39.             } 
  40.         } 
  41.  
  42.         private void sendFile(SocketChannel socketChannel, File file) throws IOException { 
  43.             FileInputStream fis = null
  44.             FileChannel channel = null
  45.             try
  46.                 fis = new FileInputStream(file); 
  47.                 channel = fis.getChannel(); 
  48.                 ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 
  49.                 int size = 0
  50.                 while ((size = channel.read(buffer)) != -1) { 
  51.                     buffer.rewind(); 
  52.                     buffer.limit(size); 
  53.                     socketChannel.write(buffer); 
  54.                     buffer.clear(); 
  55.                 } 
  56.                 socketChannel.socket().shutdownOutput(); 
  57.             } finally
  58.                 try
  59.                     channel.close(); 
  60.                 } catch(Exception ex) {} 
  61.                 try
  62.                     fis.close(); 
  63.                 } catch(Exception ex) {} 
  64.             } 
  65.         } 
  66.  
  67.         private void receiveFile(SocketChannel socketChannel, File file) throws IOException { 
  68.             FileOutputStream fos = null
  69.             FileChannel channel = null
  70.              
  71.             try
  72.                 fos = new FileOutputStream(file); 
  73.                 channel = fos.getChannel(); 
  74.                 ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 
  75.  
  76.                 int size = 0
  77.                 while ((size = socketChannel.read(buffer)) != -1) { 
  78.                     buffer.flip(); 
  79.                     if (size > 0) { 
  80.                         buffer.limit(size); 
  81.                         channel.write(buffer); 
  82.                         buffer.clear(); 
  83.                     } 
  84.                 } 
  85.             } finally
  86.                 try
  87.                     channel.close(); 
  88.                 } catch(Exception ex) {} 
  89.                 try
  90.                     fos.close(); 
  91.                 } catch(Exception ex) {} 
  92.             } 
  93.         } 
  94.     } 
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类来向服务器发送文件以及接受服务器响应文件。运行完后,分别检查服务器和客户端接收到的文件。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值