主要用到线程和线程池。没个客户端访问都要启动一个线程,然后将其存放在线程池中。这样就实现了多个用户的同时访问!
启动一个服务器,三个客户端,将其发送是信息分别为“send1”“send2”“send3”。运行结果为:
server控制台:send1
send2
send3
send1客户端:已收到信息为:send1
send2客户端:已收到信息为:send2
send3客户端:已收到信息为:send3
package testSocket_Thread;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
ServerSocket server; //其方法accept 用来监听客户端的链接
Socket socket;
static List<Socket> list = new ArrayList<Socket>();//保存链接的Socket对象
ExecutorService exec; //线程池类(说白了就是存放线程用的)
//1. Executors.newCachedThreadPool()缓存型池子,先查看池中有没有以前建立的线程,如果有,就reuse.如果没有,就建一个新的线程加入池中
//2. execute(Runnable r) 其实就是对Runnable对象调用start()方法
//3. exec.shutdownNow(); 一旦执行,线程将从线程池消失(客户端)
public Server(){
try {
server = new ServerSocket(22222);//启动监听,端口为22222
exec = Executors.newCachedThreadPool();
while(true) {
socket = server.accept();
list.add(socket);
exec.execute(new Tast(socket));
}
} catch (IOException e) {
e.printStackTrace();
}
}
class Tast implements Runnable {
Socket socket; //服务器端Socket对象
DataInputStream in; //数据输入输出流
DataOutputStream ou;
public Tast(Socket socket) throws IOException{
this.socket = socket;
in = new DataInputStream(socket.getInputStream()); //获取Socket中的出入输出流,以完成通信
ou = new DataOutputStream(socket.getOutputStream());
}
public void run() {
try {
//---------- 这里可以换成任何数据包的接受和发送 ----------
String receive = in.readUTF(); //读取客户端信息
ou.writeUTF("已收到信息为:"+receive);//向客户端发送信息
//注意:读取和发送的顺序不能错
ou.close();
in.close();
socket.close();
System.out.println(receive);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Server();
}
}
package testSocket_Thread;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Client {
static ExecutorService exec = Executors.newCachedThreadPool();
public Client() {
try {
Socket socket = new Socket("127.0.0.1", 22222);
exec.execute(new Sender(socket));
} catch (Exception e) {
e.printStackTrace();
}
}
class Sender implements Runnable {
Socket socket; //客户端Socket对象
DataInputStream in; //输入输出流
DataOutputStream ou;
public Sender(Socket s){
socket = s;
}
public void run() {
try {
in = new DataInputStream(socket.getInputStream());//获取Socket中的出入输出流,以完成通信
ou = new DataOutputStream(socket.getOutputStream());
//---------- 这里可以换成任何数据包的接受和发送 ----------
ou.writeUTF("send2"); //向服务器端发送信息
String receive = in.readUTF(); //接受服务器的反馈信息
in.close();
ou.close();
socket.close();
//exec.shutdownNow(); 一旦执行,线程将从线程池消失
System.out.println(receive);
}catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Client();
}
}
下一篇将是客户端与客户端交互信息。