使用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. FPGA In/Out Delay Timing Constaint

    先简单说说这段时间遇到的问题.FPGA采集前端scaler的视频数据.像素时钟(随路时钟),视频数据,行场同步,DE.这些信号进入FPGA后.通过CSC(颜色空间转换).输出后的图像有噪点.通过查看时 ...

  2. react篇章-React State(状态)

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...

  3. My blog in AI -- 梯度下降算法

    人工神经网络是对生物神经网络的模仿,神经网络对一个问题的学习,需要经历数据输入.网络参数的训练.超参数的调节等部分. 这次我们来详细讨论一下神经网络的学习过程. 假设我们要训练一个神经网络去识别一张图 ...

  4. 机器学习:KNN-近邻算法

    一.理论知识 1.K近邻(k-Nearest Neighbor,简称KNN)学习是一种常用的监督学习. 工作机制:给定测试样本,基于某种距离度量找出训练集中与其最靠近的k个训练样本,然后基于这k个的信 ...

  5. anaconda安装tensorflow后pip安装jieba出错的问题

    安装jieba出错,参考https://www.cnblogs.com/minsons/p/7872647.html TypeError: parse() got an unexpected keyw ...

  6. 分分钟搞定Python之排序与列表

    排序时程序中用得比较多的方法了.在Python中,最简单的排序方法摸过与使用内置的sorted(list)这个函数了,该函数一一个列表作为参数返回一个新的列表,只不过是把旧列表中的元素排过序了.原列表 ...

  7. luoguP5105 不强制在线的动态快速排序 [官方?]题解 线段树 / set

    不强制在线的动态快速排序 题解 算法一 按照题意模拟 维护一个数组,每次直接往数组后面依次添加\([l, r]\) 每次查询时,暴力地\(sort\)查询即可 复杂度\(O(10^9 * q)\),期 ...

  8. luoguP3952 [NOIP2017]时间复杂度 模拟

    原本只是想看下多久能码完时间复杂度 然后在30min内就码完了,然后一A了???? 首先,这题完全可以离线做 我们先把所有的操作读完,判断合不合法之后,再去判断和标准答案的关系 具体而言 把所有的操作 ...

  9. Alpha 冲刺报告8

    组长:吴晓晖 今天完成了哪些任务: maven和idea用的不熟啊,jar包或者war包导出来一直有问题:生气了把ide扔到服务器里去运行springboot了,卡哭了,终于可以运行了,然后debug ...

  10. 【10.17校内测试】【二进制数位DP】【博弈论/预处理】【玄学(?)DP】

    Solution 几乎是秒想到的水题叻! 异或很容易想到每一位单独做贡献,所以我们需要统计的是区间内每一位上做的贡献,就是统计区间内每一位是1的数的数量. 所以就写数位dp辣!(昨天才做了数字统计不要 ...