使用socket编程实现一个简单的文件服务器

使用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())!=-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

时间: 2024-08-24 16:22:40

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

socket编程(一):简单回射C/S程序

服务端代码: //echoSvr.c #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <str

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

原文://http://blog.csdn.net/linybo/article/details/51141960 示例程序是同步套接字程序,功能很简单,只是客户端发给服务器一条信息,服务器向客户端返回一条信息:这里只是一个简单的示例,是一个最基本的socket编程流程,在接下来的文章中,会依次记录套接字的同步和异步,以及它们的区别. 第一步:用指定的端口号和服务器的ip建立一个EndPoint对像: 第二步:建立一个Socket对像: 第三步:用socket对像的Bind()方法绑定EndPo

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

原文:http://www.cnblogs.com/xudong-bupt/archive/2013/12/29/3483059.html 部分转自:http://goodcandle.cnblogs.com/archive/2005/12/10/294652.aspx 1.   什么是TCP/IP.UDP? 2.   Socket在哪里呢? 3.   Socket是什么呢? 4.   有很多的框架,为什么还在从Socket开始? 5.   Linux C Socket简单示例 1.什么是TCP

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

与c/c++ socket编程对照见http://blog.csdn.net/aspnet_lyc/article/details/38946915 server: import socket PORT = 9999 BACKLOG = 5 MAXLINE = 1024 listenfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM) listenfd.bind(('',PORT)) listenfd.listen(BACKLOG) whil

python网络编程基础--socket的简介,以及使用socket来搭建一个简单的udp小程序

socket介绍: socket(简称套接字),是进程间通讯的一个工具,他能实现把数据从一方传输到另一方,完成不同电脑上进程之间的通讯,它好比数据的搬运工.socket应用:不夸张来说,只要跟网络相关的应用程序或者软件都使用到了socket, 比如:微信,qq等使用socket创建udp网络程序的流程:1,创建客户端套接字2,发送/接收数据3,关闭套接字使用程序展现流程 :(使用的 ide为pycharm):1,首先创建socket,在 Python 中 使用socket 模块的函数 socke

Socket 通讯,一个简单的 C/S 聊天小程序

Socket,这玩意,当时不会的时候,抄别人的都用不好,简单的一句话形容就是“笨死了”:也是很多人写的太复杂,不容易理解造成的.最近在搞erlang和C的通讯,也想试试erlang是不是可以和C#简单通讯,就简单的做了些测试用例,比较简单,觉得新手也可以接受. 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.

Python网络编程——编写一个简单的回显客户端/服务器应用

今天将python中socket模块的基本API学习完后,照着书上的实例编写一个套接字服务器和客户端.采用python3.5版本,在注释中会标明python2和python3的不同之处. 1.代码 (1)服务器端及对应代码解释 1 # ! /usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # 编写回显服务器 4 5 import socket 6 import sys 7 import argparse 8 9 # 定义常量 10 host = 'l

NodeJS+Express+Socket.io的一个简单例子

初始化一个NodeJS web应用: 打开CMD窗口. 运行cmd:"mkdir myapp",新建一个文件夹,名为myapp. 运行cmd:"cd myapp",切换到文件夹myapp. 运行cmd:"npm init",创建文件package.json. 3.Express入门应用: 在上面的CMD窗口运行cmd:"npm install express --save", 安装"express" nod

python socket编程之最简单的socket服务端

一.socket 编写server的步骤: 1.第一步是创建socket对象.调用socket构造函数.如: 1 socket = socket.socket( family, type ) family参数代表地址家族,可为AF_INET或AF_UNIX.AF_INET家族包括Internet地址,AF_UNIX家族用于同一台机器上的进程间通信.       type参数代表套接字类型,可为SOCK_STREAM(流套接字)和SOCK_DGRAM(数据报套接字).2.第二步是将socket绑定