深入理解Java网络编程

简易文件上传器

服务器

public class Server {

    public static final String FILE_UPLOAD_SUCCESS = "文件上传成功!";
    public static final String FILE_UPLOAD_FAILURE = "文件上传失败!";
    public static final int BUF_SIZE = 4 * 1024 * 1024;
    public static final int SERVER_PORT = 6666;

    public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = new ServerSocket(SERVER_PORT); // 服务器监听端口

        while (true) {
            new Thread(new ServerHandler(serverSocket.accept())).start();
        }
    }

    private static class ServerHandler implements Runnable{

        private Socket socket;

        public ServerHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {

            System.out.println(socket.getInetAddress().getHostAddress() + ":" + socket.getPort() + " CONNECTED");

            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            try {
                bis = new BufferedInputStream(socket.getInputStream());
                bos = new BufferedOutputStream(new FileOutputStream("res/server"+ new SimpleDateFormat("yyyymmddHHMMssSSS").format(new Date()) + ".avi"));

                // 为了避免文件名重复,也可以使用以下的代码:
                /*
                    int count = 0;
                    File file = new File(count + ".avi");
                    while(file.exists()){
                        file = new File(++count + ".avi");
                    }
                    FileOutputStream fos = new FileOutputStream(file);
                */
                int len = 0;
                byte[] buf = new byte[BUF_SIZE];
                while ((len = bis.read(buf))!=-1) {
                    bos.write(buf, 0, len);
                }
                socket.shutdownInput();

                PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
                pw.println(FILE_UPLOAD_SUCCESS);

                socket.shutdownOutput();
            } catch (IOException e) {
                e.printStackTrace();
            } 
        }

    }
}

客户端

public class Client {

    public static final int BUF_SIZE = 4 * 1024 * 1024;

    public static void main(String[] args) throws UnknownHostException, IOException {

        // 发送文件到服务器(指定服务端的IP和端口)
        Socket socket = new Socket(InetAddress.getLocalHost(), Server.SERVER_PORT);

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("res/client.avi"));
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());

        int len = 0;
        byte[] buf = new byte[BUF_SIZE];
        while ((len = bis.read(buf)) !=-1) {
            bos.write(buf, 0, len);
        }
        socket.shutdownOutput();

        // 获取服务端的响应信息
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = null;
        while ((line = br.readLine())!=null) {
            System.out.println(line);
        }
        socket.shutdownInput();

        socket.close();
    }

}

简易多线程端口扫描

核心是利用是否成功创建Socket。

package org.gpf;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.concurrent.*;
/**
 * 
* @ClassName: PortScanner 
* @Description: T端口扫描 
*
 */
public class PortScanner {

    private int corePoolSize = 50;
    private int maximumPoolSize = 70;
    private long keepAliveTime = 5000;
    private BlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<Runnable>();
    private ExecutorService threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,TimeUnit.MILLISECONDS,workQueue);

    /**
     * 端口扫描
     * @param ip IP地址字符串
     * @param start开始端口
     * @param end结束端口
     */
    public void scan(String ip,int start,int end){
        if (!validateIP(ip)) {
            System.err.println("Ip format is illegal.");
            return;
        }
        // 1 左移16位就是2^16 = 65536(端口的合法单位是0~65535)
        if (start < 0 || end >= (1 << 16)) {
            System.err.println("The port number is illegal.");
            return;
        }

        InetAddress inetAddress=null;
        try {
            inetAddress = InetAddress.getByName(ip);
            if (!inetAddress.isReachable(5000)) {
                System.err.println(inetAddress.getHostAddress() + " is not reachable.");
                return;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        for(int i=start;i<=end;i++){
            while(workQueue.size()>maximumPoolSize){
                try {
//                    System.out.println("Thread queue is too long,sleep 500 milliseconds.");
                    Thread.sleep(500);
                } catch (InterruptedException e) {
//                    e.printStackTrace();
                }
            }
            threadPoolExecutor.execute(new ScanWorker(inetAddress, i));
        }
        threadPoolExecutor.shutdown();
        while (!threadPoolExecutor.isTerminated()) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
//                e.printStackTrace();
            }
        }
        System.out.println("Done.");
    }

    /**
     * 验证IP地址的合法性
     * @param ip
     * @return
     */
    private boolean validateIP(String ip){
        if(ip==null||ip.length()==0) return false;
        String[] array=ip.split("\\.");
        if(array.length!=4) return false;
        for(String str:array){
            try {
                Integer.valueOf(str);
            } catch (NumberFormatException e) {
                return false;
            }
        }
        return true;
    }

    /**
     * 
    * @ClassName: ScanWorker 
    * @Description: 端口扫描的核心原理,如果能够按照ip地址+端口号的方式创建Socket不抛出异常则表示端口打开 
    * @author gaopengfei
    * @date 2015-6-26 下午9:35:53 
    *
     */
    private class ScanWorker implements Runnable{

        InetAddress inetAddress;
        int port;
        public ScanWorker(InetAddress inetAddress,int port){
            this.inetAddress=inetAddress;
            this.port=port;
        }

        @Override
        public void run() {
            Socket socket = null;
            try {

                socket = new Socket(inetAddress, port);
                socket.setSoTimeout(1000); // Socket连接超时将抛出异常
                String serviceName = getServiceName(socket.getPort());
                System.out.println("Port:" + socket.getPort() + "\tServiceName:" + serviceName + "\tIp:" + inetAddress.getHostAddress());
            } catch (IOException e) {
//                e.printStackTrace();
            } finally {
                if (socket != null && !socket.isClosed()) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        /**
         * 根据端口号获得服务名
         * @param port
         * @return
         */
        private String getServiceName(int port) {
            String name ;
            switch (port) {
                case 21:
                    name = "FTP";
                    break;
                case 23:
                    name = "TELNET";
                    break;
                case 25:
                    name = "SMTP";
                    break;
                case 80:
                    name = "HTTP";
                    break;
                case 110:
                    name = "POP";
                    break;
                case 135:
                    name="RPC";
                    break;
                case 139:
                    name = "netBIOS";
                    break;
                case 443:
                    name = "HTTPS";
                    break;
                case 1433:
                    name = "SQL server";
                    break;
                case 3306:
                    name = "MySQL";
                    break;
                case 3389:
                    name = "Terminal Service";
                    break;
                case 1521:
                    name = "Oracle";
                    break;
                case 8080:
                    name = "Tomcat";
                    break;
                default:
                    name="Unknown";
            }
            return name;
        }
    }

    public static void main(String[] args) {

        PortScanner portScanner = new PortScanner();
        portScanner.scan("127.0.0.1", 1, 1000);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值