1、实现:实现服务端与客户端一对多的关系;服务端关闭则客户端等待服务端启动后重连,客户端关闭则服务端关闭与服务端的socket连接,如果所有客户端关闭,则服务端等待客户端连接。
实现客户端向服务端单向发送数据(服务端向客户端发送数据同理)。
2、服务端:
A、服务器端创建ServerSocket,循环调用accept()等待客户端连接
B、客户端创建一个socket并请求和服务器端连接
C、服务器端接受客户端请求,创建socket与该客户建立专线连接
D、建立连接的两个socket在一个单独的线程上对话
E、服务器端继续等待新的连接
代码:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public class SocketServer {
private static ServerSocket serverSocket = null;
private static Map<String, ModelClass> info = new ConcurrentHashMap<>();
static {
try {
serverSocket = new ServerSocket(9090);
} catch (IOException e) {
System.out.println("create serverSocket error: " + e.getMessage());
}
}
public static void main(String[] args) throws IOException {
// 定时打印接收到的数据
new Thread(new Runnable( ) {
@Override
public void run() {
while (true) {
Iterator<Map.Entry<String, ModelClass>> it = info.entrySet().iterator();
while(it.hasNext()) {
Entry<String, ModelClass> entry = it.next();
ModelClass mc = entry.getValue();
System.out.println(mc.name);
System.out.println(mc.m1.get(0));
System.out.println(mc.m2.get(0).value);
System.out.println();
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
}).start();
// 等待客户端连接
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
System.out.println("*****服务器已启动,等待客户端连接*****");
Socket socket = serverSocket.accept();
System.out.println("*****已连接客户端*****");
new SST(socket).start();
} catch (Exception e) {
System.out.println("socket accept error: " + e.getMessage());
}
}
}
}).start();
}
static class SST extends Thread {
private Socket socket;
private String key;
public SST(Socket socket) {
this.socket = socket;
key = socket.getInetAddress().toString() + "/" + socket.getPort();
}
@Override
public void run() {
// BufferedReader br = null; // 读取客户端输入的文件流
ObjectInputStream ois = null; // 读取客户端输入的对象流
try {
while (true) {
// br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// String msg = null;
// while((msg = br.readLine()) != null) {
// System.out.println("get msg---" + socket.getInetAddress() + "/" + socket.getPort());
// System.out.println("client msg: " + msg);
// }
ois = new ObjectInputStream(socket.getInputStream());
Object obj = ois.readObject();
ModelClass mc = (ModelClass)obj;
info.put(key, mc);
}
} catch (Exception e) {
System.out.println("get msg error: " + e.getMessage());
} finally {
if (info.containsKey(key)) {
info.remove(key);
}
try {
// if (br != null) {
// br.close();
// }
if (ois != null) {
ois.close();
}
} catch (IOException e) {
System.out.println("br close error: " + e.getMessage());
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
}
}
}
3、客户端:
A、用服务器的IP地址和端口号实例化Socket对象。
B、获得Socket上的流,以进行读写。
C、关闭打开的流和Socket。
代码:
import java.io.ObjectOutputStream;
import java.net.Socket;
public class SocketClient {
ModelClass mc;
public SocketClient() {
new Thread(new Runnable() {
@Override
public void run() {
try {
client();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}).start();
}
public void send(ModelClass mc) {
this.mc = mc;
}
private void client() throws Exception {
Socket socket = null;
ObjectOutputStream oos = null;
try {
while(true) {
System.out.println("create new socket!");
try {
socket = new Socket("127.0.0.1", 9090);
while (true) {
if (mc == null) {
Thread.sleep(1000);
continue;
}
System.out.println("out object!");
oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(mc);
mc = null;
}
} catch (Exception e) {
System.out.println("socket error: " + e.getMessage());
}
Thread.sleep(5000);
}
} finally {
if (socket != null) {
socket.close();
}
if (oos != null) {
oos.close();
}
}
}
}
4、客户端实例:
import socket.ModelClass.InnerModel;
import socket.ModelClass.Status;
public class Client2 {
private static SocketClient client;
public static void main(String[] args) throws Exception {
client = new SocketClient();
new Client2().func();
}
public void func() throws InterruptedException {
ModelClass mc = new ModelClass();
mc.name = "client2";
mc.m1.add(Status.NA);
mc.m2.clear();
InnerModel im = new InnerModel();
while(true) {
im.value = "client2: " + System.currentTimeMillis();
mc.m2.add(im);
client.send(mc);
Thread.sleep(2000);
}
}
}
5、对象model:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class ModelClass implements Serializable {
private static final long serialVersionUID = 1000L;
String name;
List<Status> m1 = new ArrayList<>();
List<InnerModel> m2 = new ArrayList<>();
static class InnerModel implements Serializable {
private static final long serialVersionUID = 1001L;
String value;
}
public enum Status {
OK,
ERROR,
NA,
WARNING,
FATAL;
}
}
来源:https://www.cnblogs.com/lglbky/p/11043816.html