一、客户端的:(main方法启动就可以)
package com.feng.test.simpleSocket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
*socket客户端,用于发送请求,接收返回值<br>
* @author lenovo
*
*/
public class SimpleSocketClient extends Thread{
//全局变量
private String ip;//IP地址
private Integer port;//端口号
private String param;
//方法重载,重载几个构造方法
/**
* 客户端构造<br>
*/
public SimpleSocketClient() {
super();
}
/**
* 客户端构造<br>
* @param ip
* @param port
*/
public SimpleSocketClient(String ip, Integer port,String param) {
this.ip = ip;
this.port = port;
this.param = param;
}
/**
* 业务处理<br>
*/
@Override
public void run() {
try {
String result = sendRequest(param);
System.out.println("请求参数:"+param+";处理结果:"+result);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 发送请求<br>
* @param param
* @throws Exception
*/
public String sendRequest(String param) throws Exception{
String result = "";//返回值
//参数校验
if(param==null||"".equals(param) ){
throw new Exception("请求参数异常:"+param);//若发生异常,下面不会走
}
//若没有参数异常
//根据ip,port,new一个socket实例
Socket socket = new Socket(ip, port);
FutureTask<String> futureTask = new FutureTask<String>(new ClientThread(socket));//创建一个futuretask将在运行时,执行被调用。
new Thread(futureTask).start();
//获取这个socket对应输出流,取出数据
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.print(param);
ps.flush();
//关闭socket输出流,同时把流内的数据输出完
socket.shutdownOutput();
//等待服务端返回数据,一直阻塞着,直到返回数据
while(true){
if(futureTask.get() != null){
result = futureTask.get();
break;
}
}
//关闭相关的流
ps.close();
return result;
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
SimpleSocketClient sc = new SimpleSocketClient("127.0.0.1", 9091,"");
try {
String result = sc.sendRequest("1000");
System.out.println("请求参数:"+"1000"+";处理结果:"+result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 带返回值的方法<br>
* @author lenovo
*
*/
class ClientThread implements Callable<String>{//实现Callable接口,即可实现待返回值得线程
private Socket socket;
private BufferedReader br ;//字符缓冲流
/**
* 构造方法<br>
* @param socket
* @throws IOException
*/
public ClientThread(Socket socket) throws IOException {
this.socket = socket;
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
/**
*处理请求<br>
*/
public String call() throws Exception {
StringBuffer sb = new StringBuffer();
String content = "";
while((content = br.readLine()) != null){
sb.append(content);
}
System.out.println("从服务端获取的数据:"+sb.toString());
//关闭相应的流
br.close();
socket.close();
return sb.toString();//返回请求结果
}
}
二、服务端:
package com.feng.test.simpleSocket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* socket服务端,用于接收客户端请求,并回复请求<br>
* @author lenovo
*
*/
public class SimpleSocketServer extends Thread{
//端口号
private static Integer port = 9091;
//单线程池
private static ExecutorService executorService = Executors.newSingleThreadExecutor();
public static void main(String[] args) {
try {
System.out.println("-----------------服务端已经启动-----------------");
//A server socket waits for requests to come in over the network.
//等待请求连接
ServerSocket ss = new ServerSocket(port);
while(true){
//Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.
//监听客户端socket连接,获得socket
Socket socket = ss.accept();
executorService.submit(new HandleSocketThread(socket));
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 处理线程
*/
public void run() {
try {
//A server socket waits for requests to come in over the network.
//等待请求连接
ServerSocket ss = new ServerSocket(port);
//阻塞获得socket,处理
while(true){
//Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.
//监听客户端socket连接,获得socket
Socket socket = ss.accept();
executorService.submit(new HandleSocketThread(socket));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* socket处理线程
* @author lenovo
*
*/
class HandleSocketThread implements Runnable{
private Socket socket ;
private BufferedReader br;
public HandleSocketThread(Socket socket) throws IOException {
this.socket = socket;
//socket中获得输入流
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//流的转换字节流->字符流->缓冲字符流
}
public void run() {
StringBuffer sb = new StringBuffer();
String content = "";
try {
while((content = br.readLine())!=null){
sb.append(content);
}
System.out.println("客户端的请求内容:"+sb.toString());
handle(sb.toString(),socket);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 处理业务逻辑
* @param content
* @throws Exception
*/
public void handle(String content,Socket socket) throws Exception{
String result = content + "_"+((int)(Math.random()*1000000));//处理业务,简单化
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("服务端处理结果:"+result);
bw.write(result);
bw.flush();
Thread.sleep(2000);
bw.close();
socket.close();
}
}
三.先启动服务端,再启动客户端测试:
测试结果:
1.服务端:
2.客户端:
SUCCESS!