服务器
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 workQueue = new LinkedBlockingDeque();
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);
}
}