使用socket编程实现一个简单的文件服务器。客户端程序实现put功能(将一个文件从本地传到文件服务器)get功能(从文件服务器取一远程文件存为本地文件)。客户端和文件服务器不在同一台机器上。
put [-h hostname] [-p portname] local_filenameremote_filename
get [-h hostname] [-p portname] remote_filenamelocal_filename
程序如下:

客户端Client.java

package com.cn.gao;
import java.net.*;
import java.io.*;
/**
*
* 用Socket实现文件服务器的客户端
* 包含发送文件和接收文件功能
*
*/
public class Client {
private Socket client;
private boolean connected;
//构造方法
public Client(String host,int port){
try {
//创建Socket对象
client = new Socket(host,port);
System.out.println("服务器连接成功!");
this.connected = true;
} catch (UnknownHostException e) {
System.out.println("无法解析的主机!");
this.connected = false;
} catch (IOException e) {
System.out.println("服务器连接失败!");
this.connected = false;
closeSocket();
}
}
//判断是否连接成功
public boolean isConnected(){
return connected;
}
//设置连接状态
public void setConnected(boolean connected){
this.connected = connected;
}
/**
* 发送文件方法
* @param localFileName 本地文件的全路径名
* @param remoteFileName 远程文件的名称
*/
public void sendFile(String localFileName, String remoteFileName){
DataOutputStream dos = null; //写Socket的输出流
DataInputStream dis = null; //读取本地文件的输入流
if(client==null) return;
File file = new File(localFileName);
//检查文件是否存在
if(!file.exists()){
System.out.println("本地文件不存在,请查看文件名是否写错!");
this.connected = false;
this.closeSocket();
return;
}
try {
//初始化本地文件读取流
dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
//将指令和文件发送到Socket的输出流中
dos = new DataOutputStream(client.getOutputStream());
//将远程文件名发送出去
// System.out.println(remoteFileName);
dos.writeUTF("put "+remoteFileName);
//清空缓存,将文件名发送出去
dos.flush();
//开始发送文件
int bufferSize = 10240;
byte[] buf = new byte[bufferSize];
int num =0;
while((num=dis.read(buf))!=-1){
dos.write(buf, 0, num);
}
dos.flush();
System.out.println("文件发送成功!");
} catch (IOException e) {
System.out.println("文件传输错误!");
closeSocket();
} finally{
try {
dis.close();
dos.close();
} catch (IOException e) {
System.out.println("输入输出错误!");
}
}
}
/**
* 接收文件方法
* @param remoteFileName 本地文件的全路径名
* @param localFileName 远程文件的名称
*/
public void receiveFile(String remoteFileName, String localFileName){
DataOutputStream dos = null; //写Scoket的输出流
DataInputStream dis = null; //读Socket的输入流
DataOutputStream localdos = null; //写本地文件的输出流
if(client==null) return;
try {
localdos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(localFileName)));
//将指令和文件名发送到Socket的输出流中
dos = new DataOutputStream(client.getOutputStream());
//将远程文件名发送出去
dos.writeUTF("get "+remoteFileName);
dos.flush();
//开始接收文件
dis = new DataInputStream(new BufferedInputStream(client.getInputStream()));
int bufferSize = 10240;
byte[] buf = new byte[bufferSize];
int num = 0;
while((num=dis.read(buf))!=-1){
localdos.write(buf, 0, num);
}
localdos.flush();
System.out.println("数据接收成功!");
} catch (FileNotFoundException e) {
System.out.println("文件没有找到!");
closeSocket();
} catch (IOException e) {
System.out.println("文件传输错误!");
} finally {
try {
dos.close();
localdos.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//关闭端口
public void closeSocket(){
if(client!=null){
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 主方法调用上述方法
* @param args
* 将本地文件上传到远程服务器
* put[-h hostname][-p portname]local_filename remote_filename
* 从远程服务器上下载文件
* get[-h hostname][-p portname]remote_filename local_filename
*/
public static void main(String[] args){
//服务器默认端口为8888
if(args.length!=7){
System.out.println("参数数目不正确!");
return;
}
String hostName = args[2];
int port = 0;
String localFileName = "";
String remoteFileName = "";
Client client = null;
try {
port = Integer.parseInt(args[4]);
} catch (NumberFormatException e) {
System.out.println("端口号输出格式错误!");
return;
}
if(args[0].equals("put")){
//上传文件
client = new Client(hostName,port);
localFileName = args[5];
remoteFileName = args[6];
// System.out.println(remoteFileName);
if(client.isConnected()){
client.sendFile(localFileName, remoteFileName);
client.closeSocket();
}
}else if(args[0].equals("get")){
//下载文件
client = new Client(hostName,port);
localFileName = args[6];
remoteFileName = args[5];
if(client.isConnected()){
client.receiveFile(remoteFileName, localFileName);
client.closeSocket();
}
}else{
System.out.println("命令输入不正确,正确命令格式如下:");
System.out.println("put -h hostname -p portname local_filename remote_filename");
System.out.println("get -h hostname -p portname remote_filename local_filename");
}
}
}

服务器端Server.java

package com.cn.gao;
import java.io.*;
import java.net.*;
/**
* 实现服务器端
* 用于接收上传的数据和供客户端下载数据
* @author DELL
*
*/
public class Server {
private int port;
private String host;
private String dirPath;
private static ServerSocket server; public Server(int port,String dirPath){
this.port = port;
this.dirPath = dirPath;
this.server = null;
} public void run(){
if(server==null){
try {
server = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("服务已启动...");
while(true){
try {
//通过ServerSocket的accept方法建立连接,并获取客户端的Socket对象
Socket client = server.accept();
if(client==null) continue;
new SocketConnection(client,this.dirPath).run();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 实现服务器端的数据传输
* @author DELL
*
*/
public class SocketConnection extends Thread{
private Socket client;
private String filePath; public SocketConnection(Socket client, String filePath){
this.client = client;
this.filePath = filePath;
} public void run(){
if(client==null) return;
DataInputStream in= null; //读取Socket的输入流
DataOutputStream dos = null; //写文件的输出流
DataOutputStream out = null; //写Socket的输出流
DataInputStream dis = null; //读文件的输入流
try {
//访问Scoket对象的getInputStream方法取得客户端发送过来的数据流
in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
String recvInfo = in.readUTF(); //取得附带的指令及文件名
// System.out.println(recvInfo);
String[] info = recvInfo.split(" ");
String fileName = info[1]; //获取文件名
// System.out.println(fileName);
if(filePath.endsWith("/")==false&&filePath.endsWith("\\")==false){
filePath+="\\";
}
filePath += fileName;
if(info[0].equals("put")){
//从客户端上传到服务器
//开始接收文件
dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File(filePath))));
int bufferSize = 10240;
byte[] buf = new byte[bufferSize];
int num =0;
while((num=in.read(buf))!=-1){
dos.write(buf, 0, num);
}
dos.flush();
System.out.println("数据接收完毕!");
}else if(info[0].equals("get")){
//从服务器下载文件到客户端
dis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
//开始发送文件
int bufferSize = 10240;
byte[] buf = new byte[bufferSize];
out = new DataOutputStream(client.getOutputStream());
int num =0;
while((num=dis.read(buf))!=-1){
out.write(buf, 0, num);
}
out.flush();
System.out.println("发送成功!");
}
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if(out!=null) out.close();
if(in!=null) in.close();
if(dos!=null) dos.close();
if(dis!=null) dis.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} public static void main(String[] args){
//设置服务器端口
int port = 8888;
//设置服务器文件存放位置
String dirPath = "D:\\FTPService\\";
new Server(port,dirPath).run();
}
}

参数输入方式示例

put -h 127.0.0.1 -p 8888 D:\\data.xls data.xls

get -h 127.0.0.1 -p 8888 data.xls D:\\data.xls

使用socket编程实现一个简单的文件服务器的更多相关文章

  1. Win Socket编程原理及简单实例

    [转]http://www.cnblogs.com/tornadomeet/archive/2012/04/11/2442140.html 使用Linux Socket做了小型的分布式,如Linux ...

  2. C#版 Socket编程(最简单的Socket通信功能)

    示例程序是同步套接字程序,功能很简单,只是客户端发给服务器一条信息,服务器向客户端返回一条信息:这里只是一个简单的示例,是一个最基本的socket编程流程,在接下来的文章中,会依次记录套接字的同步和异 ...

  3. Linux C Socket编程原理及简单实例

    部分转自:http://goodcandle.cnblogs.com/archive/2005/12/10/294652.aspx 1.   什么是TCP/IP.UDP? 2.   Socket在哪里 ...

  4. java基础之Socket编程概述以及简单案例

    概述: 用来实现网络互连的 不同的计算机上 运行的程序间 可以进行数据交互  也就是用来在不同的电脑间, 进行数据传输. 三大要素: IP地址: 设备(电脑,手机,ipad)在网络中的唯一标识. 组成 ...

  5. go web编程——实现一个简单分页器

    在go web编程中,当需要展示的列表数据太多时,不可避免需要分页展示,可以使用Go实现一个简单分页器,提供各个数据列表展示使用.具体需求:1. 可展示“首页”和“尾页”.2. 可展示“上一页”和“下 ...

  6. python socket编程实现的简单tcp迭代server

    与c/c++ socket编程对照见http://blog.csdn.net/aspnet_lyc/article/details/38946915 server: import socket POR ...

  7. Linux网络编程:一个简单的正向代理服务器的实现

    Linux是一个可靠性非常高的操作系统,但是所有用过Linux的朋友都会感觉到, Linux和Windows这样的"傻瓜"操作系统(这里丝毫没有贬低Windows的意思,相反这应该 ...

  8. [C#] Socket 通讯,一个简单的聊天窗口小程序

    Socket,这玩意,当时不会的时候,抄别人的都用不好,简单的一句话形容就是“笨死了”:也是很多人写的太复杂,不容易理解造成的.最近在搞erlang和C的通讯,也想试试erlang是不是可以和C#简单 ...

  9. Python 元类编程实现一个简单的 ORM

    概述 什么是ORM? ORM全称"Object Relational Mapping",即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码 ...

随机推荐

  1. wampserver的安装和使用

    首先想说一下通常搭建WAMP平台的时候主要分为散装包搭建和集成包搭建过程. 散装包搭建就是把PHP,Apache,MySQL等下载下来,一个个的安装,其过程灰常的复杂,而且需要配置的系统变量和修改的文 ...

  2. IOS常用第三方类库

    开发几个常用的开源类库及下载地址: 1.json json编码解码 2.GTMBase64 base64编码解码 3.TouchXML xml解析 4.SFHFKeychainUtils 安全保存用户 ...

  3. 七牛云整合Ueditor的ThinkPHP版本

    首先去七牛云官网下载phpSDK工具放在Think/library/Vendor下. ueditor后台调用方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  4. 《Android源码设计模式》--状态模式--责任链模式--解释器模式--命令模式--观察者模式--备忘录模式--迭代器模式

    [状态模式] No1: Wifi设置界面是一个叫做WifiSetting的Fragment实现的 No2: 在不同的状态下对于扫描Wifi这个请求的处理是完全不一样的.在初始状态下扫描请求被直接忽略, ...

  5. CSUOJ 1217 奇数个的那个数 位运算

    Description 给定些数字,这些数中只有一个数出现了奇数次,找出这个数. Input 每组数据第一行n表示数字个数,1 <= n <= 2 ^ 18 且 n % 2 == 1. 接 ...

  6. Java 集合之 Collection

    集合就是一组数的集合,就像是一个容器,但是我们应该清楚的是集合中存放的都是对象的引用,而不是真正的实体.而我们常说的集合中的对象其实指的就是对象的引用. 我们可以把集合理解为一个小型数据库,用于存放数 ...

  7. 网络图片嗅探工具driftnet

    网络图片嗅探工具driftnet   图片是网络数据传输的重要内容.Kali Linux内置了一款专用工具drifnet.该工具可以支持实时嗅探和离线嗅探.它可以从数据流中提取JPEG和GIF这两种网 ...

  8. python中的urlencode和urldecode

    python将字符串转化成urlencode ,或者将url编码字符串decode的方法: 方法1: urlencode:urllib中的quote方法 >>> from urlli ...

  9. tomcat启动startup.bat一闪而过的问题处理方式

    tomcat在启动时,会读取环境变量的信息,需要一个CATALINA_HOME 与JAVA_HOME的信息,CATALINA_HOME即tomcat的主目录,JAVA_HOME即Java安装的主目录, ...

  10. JavaSE基础之矩阵运算

    JavaSE基础之矩阵运算 1.矩阵类:Matrix.java 包括矩阵的加.乘运算,行列式的求解,最大最小元素等 package cn.com.zfc.help; import java.text. ...