具体用法参考jdk:
http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4
为了方便理解ServerSocket
服务器与客户端的关系以及数据的交换
请看下图:
下面直接演示ServerSocket实现的几个功能:
一、 客户端服务端发信息给服务端
二、模拟一个广播电台(服务端向客服端发送信息)
三、模拟一个对讲机(半双工模式)只能交替通话,不能同时通话
四、做一个木马文件
五、客户端发送一个命令到服务端,服务端接收之后,在服务器执行这个命令,并把执行的结果返回给客户端
示例中所用到的java包:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
一、 客户端服务端发信息给服务端
/**
* ServerSocket 实现服务端与客户端通讯
*
* @author PeicongHe
*
*/
public class ServerSocketDemo {
/**
* 步骤:
* 1 先创建一个服务端,端口号为:8888
* 2 等待客户端连接
* 3 创建一个客户端的输入流(用于将信息发送给服务端)
* 4 服务端打印并显示信息
*/
public static void test1() {
try {
ServerSocket serverSocket = new ServerSocket(8888); // 创建一个服务端,监听端口8888
Socket socket = serverSocket.accept(); // 等待客户端连接过来
System.out.println("来客IP: " + socket.getInetAddress()); // 获取来客的IP地址
InputStream is = socket.getInputStream();// 客户端的输入流
Scanner sc = new Scanner(is);
String msg = "";
while (sc.hasNextLine()) {
msg = sc.nextLine();
System.out.println(msg);
if (msg.equals("exit")) {
System.out.println("我要退出!");
System.exit(0);
}
}
sc.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Static void main(String[] args){
test1();
}
}
/**
* 增加自动回复功能
* 步骤:
* 1 在获取客户端输入流前添加一个客户端输出流(用于输出自动回复内容)
* 2 打印输出流信息
* 3 刷新打印
*/
public static void test2() {
try {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
System.out.println("来客ip: " + socket.getInetAddress());
// 增加一个自动回复
OutputStream os = socket.getOutputStream();// 添加一个客户端输出
PrintWriter pw = new PrintWriter(os);// 打印出来
pw.print("welcome to my home!");// 打印的信息
pw.flush();// 刷新打印
InputStream is = socket.getInputStream();
Scanner sc = new Scanner(is);
String msg = "";
while (sc.hasNextLine()) {
msg = sc.nextLine();
System.out.println(msg);
if (msg.equals("exit")) {
System.out.println("再见!我要退出!");
System.exit(0);
}
}
sc.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
二、模拟一个广播电台(服务端向客服端发送信息)
/**
* 模拟一个广播电台,特点是只能服务端说话,不能客户端说话
* 步骤:
* 1 创建一个服务端
* 2 接收一个客户端
* 3 创建一个服务端的输入流(用于存储系统输入的数据流)
* 4 创建一个客服的输出流(用于在客服上显示出数据)
* 5 扫描打印,刷新打印
*/
public static void broadcast(){
try {
ServerSocket server = new ServerSocket(8888);// 创建一个服务端,监听端口8888
Socket socket = server.accept();// 等待客户端连接过来
System.out.println("Ip: "+socket.getLocalAddress()+" 成功接入! ");
OutputStream serverops1 = socket.getOutputStream();// 获取来客的IP地址
//自动回复
PrintWriter pw1 = new PrintWriter(serverops1);
pw1.write("欢迎接入服务器!");
pw1.flush();
InputStream serverips = System.in;//在服务端输入广播内容做为输入流
OutputStream serverops2 = socket.getOutputStream();//输出流用于传输信息给客户端
PrintWriter pw = new PrintWriter(serverops2);
//获取信息
Scanner sc = new Scanner(serverips);
String msg="";
while(sc.hasNextLine()){
msg = sc.nextLine();
pw.println(msg);//输出信息
pw.flush();
if(msg.equals("exit")){
System.out.println("服务端讲话完毕,再见!");
System.exit(0);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
三、模拟一个对讲机(半双工模式)只能交替通话,不能同时通话
/**
* 步骤:
* 1 创建服务端
* 2 接收一个客户端
* 3 创建一个服务端的输入流(用于在服务端输入)
* 4 创建一个客户端的输出流(用于在客户端显示)
* 5 创建一个客户端的输入流 (用于在服务端显示)
* 6 获取客户端发送的信息
* 7 每次客户端输入一段话过来,我们都要从键盘输入一段话,并且发送给客户端
*/
public static void connunication(){
try {
ServerSocket server = new ServerSocket(8888);// 创建一个服务端,监听端口8888
Socket socket = server.accept();//接收一个客户端
Scanner scannerSystemIn = new Scanner(System.in);//创建一个服务端的输入流(用于在服务端输入)
PrintWriter pw = new PrintWriter(socket.getOutputStream());//创建一个客户端的输出流(用于在客户端显示)
Scanner scanner =new Scanner(socket.getInputStream());//创建一个客户端的输入流 (用于在服务端显示)
String msg = "";
String serverMsg ="";
while(scanner.hasNextLine()){//获取客户端发送的信息
msg=scanner.nextLine();
System.out.println("客户端的输入: "+msg);
//当输入exit 退出循环,结束通信
if(msg.equals("exit")||serverMsg.equals("exit")){
System.out.println("退出连接!");
System.exit(0);
}
//每次客户端输入一段话过来,我们都要从键盘输入一段话,并且发送给客户端
if(scannerSystemIn.hasNextLine()){
serverMsg = scannerSystemIn.nextLine();
System.out.println("服务端输入: " + serverMsg);
pw.println("服务端说:"+serverMsg);
pw.flush();
}
}
//关闭流
pw.close();
scannerSystemIn.close();
scanner.close();
} catch (IOException e) {
e.printStackTrace();
}
四、做一个木马文件
/**
* 客户端可以通过输入一个文件名传给服务端,服务端就会根据文件的地址,将文件的内容返回给客户端
*/
public static void test5() {
try {
// 1:创建一个服务端,监听一个端口
ServerSocket serverSocket = new ServerSocket(8888);
// 2:获取一个客户端对象
Socket socket = serverSocket.accept();
InputStream is = socket.getInputStream();
Scanner scanner = new Scanner(is);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
while (scanner.hasNextLine()) {
// 3 接受客户端的一个文件名
String fileName = scanner.nextLine();
// 4:读取文件
String content = getContentFromFile(fileName);
// 5:把文件内容返回给客户端
pw.println(content);
pw.flush();
}
is.close();
socket.close();
pw.close();
// 4:
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
五、客户端发送一个命令到服务端,服务端接收之后,在服务器执行这个命令,并把执行的结果返回给客户端
/**
* 功能: 客户端发送命令控制服务端,服务端返回执行结果给客户端
* 步骤:
* 1、获取客户端发送给服务端的命令
* 2、服务器运用进程的语句执行命令,保存执行的结果
* 3、判断执行结果
* 4、将执行的结果发送给客户端
*/
public static void test() {
try {
ServerSocket server = new ServerSocket(8888);
// 由于我们平时测试的时候,每次出错或者每次在客户端断开连接的时候,服务端都会自动断开
// 为了解决这个问题,我们写了一个循环,当一个连接退出时,服务端自动进入下一个连接
while (true) {
Socket socket = server.accept();
Scanner scanner = new Scanner(socket.getInputStream());
PrintWriter pw = new PrintWriter(socket.getOutputStream());
String command = "";
String p1Content = "";
String p2Content = "";
// String p1go = "";
while (scanner.hasNextLine()) {
command = scanner.nextLine();
Process p = Runtime.getRuntime().exec(command);
// 需要从进程执行后的结果中得到一个输入流,这里我们想要的信息
Scanner p1go = new Scanner(p.getInputStream());
while (p1go.hasNextLine()) {// 输出到客户端
p1Content = p1go.nextLine();
pw.println(p1Content);
pw.flush();
}
// 如果命令执行错误,就会有一个错误流
Scanner p2er = new Scanner(p.getErrorStream());
while (p2er.hasNextLine()) {
p2Content = p2er.nextLine();
}
// 如果错误流不为空,就把错误信息输出到客户端
if (!p2Content.equals("")) {
pw.print(p2Content);
pw.flush();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}