使用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. HBase结合MapReduce批量导入(HDFS中的数据导入到HBase)

    HBase结合MapReduce批量导入 package hbase; import java.text.SimpleDateFormat; import java.util.Date; import ...

  2. 远程连接mysql root账号报错:2003-can't connect to MYSQL serve

    1.远程连接Linux系统,登录数据库:mysql -uroot -p(密码) 2.修改root账号的设置: GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDE ...

  3. Java 集合之 Collection

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

  4. [转载] 你所不知道的TIME_WAIT和CLOSE_WAIT

    前言 本文转载自 https://mp.weixin.qq.com/s/FrEfx_Yvv0fkLG97dMSTqw.很久前看到Vincent Bernat在博客中写了一遍关于TCP time-wai ...

  5. Win10如何配置Jdk环境变量

    对于每一位做Java开发的朋友来说,Jdk是必须要安装的,安装好了Jdk,其实并没有结束,还需要配置Jdk的环境变量,系统在不断地更新,小编给大家介绍一下如何在Win10下配置Jdk,并检测是否配置成 ...

  6. 列表中字符串按照某种规则排序的方法(python)

    有时候处理数据时,想要按照字符串中的数字的大小进行排序. 譬如,存在一组记录文件,分别为‘1.dat’,'2.dat'... 当我把该文件夹中的所有记录文件名读到一个列表中,这些字符串的排列方式为: ...

  7. [BZOJ5298][CQOI2018]交错序列(DP+矩阵乘法)

    https://blog.csdn.net/dream_maker_yk/article/details/80377490 斯特林数有时并没有用. #include<cstdio> #in ...

  8. [BZOJ3309]DZY Loves Math(莫比乌斯反演+线性筛)

    $\sum\limits_{T=1}^{n}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum\limits_{d|T}f(d)\mu(\fr ...

  9. LOJ P3959 宝藏 状压dp noip

    https://www.luogu.org/problemnew/show/P3959 考场上我怎么想不出来这么写的,状压白学了. 直接按层次存因为如果某个点在前面存过了则肯定结果更优所以不用在意各点 ...

  10. Codeforces 1085G(1086E) Beautiful Matrix $dp$+树状数组

    题意 定义一个\(n*n\)的矩阵是\(beautiful\)的,需要满足以下三个条件: 1.每一行是一个排列. 2.上下相邻的两个元素的值不同. 再定义两个矩阵的字典序大的矩阵大(从左往右从上到下一 ...