版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/P923284735/article/details/89177671
Socket
建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
短连接
服务端和客户端建立连接后,客户端获取流来和服务端通讯,通讯完毕后,关闭流,关闭Socket连接。
长连接
服务端和客户端建立连接后,客户端获取流来和服务端通讯,通讯完毕不关闭流,不关闭Socket,一直保持着通讯。
服务端代码
Socket服务端启动线程:
package com.jeesite.modules.socket;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* @Desc 服务端线程
* @author PGQing
*
*/
public class SocketServerThread implements Runnable {
private static final int PORT = 8989;
private static final String CHARSET = "UTF-8";
List<Socket> sockets = new ArrayList<>();
ServerSocket server = null;
public SocketServerThread() {
try {
server = new ServerSocket(PORT);
System.out.println("Socket服务启动成功~");
} catch (IOException e) {
System.out.println("初始化Socket服务异常:\n");
e.printStackTrace();
}
}
@Override
public void run() {
try {
while (true) {
// 建立socket接口,accept方法等到用户连接才会继续执行
Socket socket = server.accept();
socket.setKeepAlive(true);
// 在服务器显示连接的电脑
String message = socket.getInetAddress().getHostAddress().toString();
System.out.println("客户端:" + message + "已连接~");
// 将已有的连接添加到集合中
sockets.add(socket);
// 向客户端发送登录信息
SendMessageToClient(message);
// 建立读取客户端数据的线程
Thread t = new Thread(new ReadClientDataThread(socket));
t.start();
}
} catch (Exception e) {
System.out.println("Socket运行中出现了异常:\n");
e.printStackTrace();
}
}
public void SendMessageToClient(String message) {
// 遍历集合,寻找已经链接的客户端
for (Socket s : sockets) {
// 判断是否已经连接
if (null != s && s.isConnected()) {
try {
OutputStream os = s.getOutputStream();
os.write(message.getBytes(CHARSET));
os.flush();
} catch (Exception e) {
System.out.println("Socket服务向客户端发送数据出现了异常:\n");
e.printStackTrace();
}
}
}
}
}
Socket建立通讯后的读取数据线程:
package com.jeesite.modules.socket;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import com.jeesite.modules.utils.HttpUtils;
/**
* @Desc 读取客户端数据的线程
* @author PGQing
*
*/
public class ReadClientDataThread implements Runnable {
private InputStream is = null;
public ReadClientDataThread(Socket socket) {
try {
is = socket.getInputStream();
} catch (IOException e) {
System.out.println("获取已连接会话中的输入流出现了错误:\n");
e.printStackTrace();
}
}
@Override
public void run() {
try {
int len = 0;
byte[] bytes = new byte[1024];
String temp = null;
while ((len = is.read(bytes))!=-1) {
temp = new String(bytes, 0, len);
// 发送GPS信息请求
Map<String, String> map = new HashMap<>();
map.put("param", temp);
HttpUtils.send("http://localhost:8085/jyzs/socket/saveInfo", map, 10);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
线程启动,拿Spring Boot 为示例:
@SpringBootApplication
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
//线程启动
Thread mainThread = new Thread(new SocketServerThread());
mainThread.start();
}
}