使用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. mysql 删除重复项

    DELETE FROM j_rank_rise_record WHERE id NOT IN ( SELECT id FROM ( SELECT * FROM j_rank_rise_record g ...

  2. 在qemu上运行BusyBox

    BusyBox 前文“在qemu环境中用gdb调试Linux内核”和“Initramfs 原理和实践”分别描述了怎么用qemu来运行一个编译好的内核,以及怎么指定initramfs,但都是简单的演示. ...

  3. Python内存管理方式和垃圾回收算法解析

    在列表,元组,实例,类,字典和函数中存在循环引用问题.有 __del__ 方法的实例会以健全的方式被处理.给新类型添加GC支持是很容易的.支持GC的Python与常规的Python是二进制兼容的. 分 ...

  4. Python如何将RGB图像转换为Pytho灰度图像?

    我正尝试使用matplotlib读取RGB图像并将其转换为灰度.在matlab中,我使用这个: 1 img = rgb2gray(imread('image.png')); 在matplotlib t ...

  5. ArrayList,Vector,LinkedList

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 数组列表 和 向量Vector, 都是使用数组方式存储. 向量 使用了 同步synchr ...

  6. 鸟哥的私房菜:Bash shell(六)-管道命令

    就如同前面所说的, bash 命令执行的时候有输出的数据会出现! 那么如果这群数据必需要经过几道手续之后才能得到我们所想要的格式,应该如何来设定? 这就牵涉到管线命令的问题了 (pipe) ,管线命令 ...

  7. python开发_logging_日志处理

    在很多编程语言中,都会出现日志处理操作,python也不例外... 接下来我们来看看python中的logging模块 ''' python中,logging模块主要是处理日志的. 所谓日志,可理解为 ...

  8. 读书笔记_Effective_C++_条款三十八:通过复合塑模出has-a或者is-implemented-in-terms-of

    如果说public是一种is-a的关系的话,那么复合就是has-a的关系.直观来说,复合就是在一个类中采用其他类的对象作为自身的成员变量,可以举个例子,像下面这样: class Person { pr ...

  9. Redis系列之(一):10分钟玩转Redis

    1. Redis介绍 Redis是一个开源的使用ANSI C语言编写.基于内存的Key-Value数据库. 它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集 ...

  10. 【原】MySQL实用SQL积累

    [文档简述] 本文档用来记录一些常用的SQL语句,以达到快速查询的目的. [常用SQL] 1.mysql数据库中获取某个表的所有字段名 select COLUMN_NAME from informat ...