目录
结尾有借鉴视频内容,不知名博主讲的很不错便于理解。
第一版
实现效果:
Server端:
public class Server {
public static void main(String[] args) {
System.out.println("Socket服务器开始运行...");
try {
ServerSocket serverSocket = new ServerSocket(9999);
while(true){
Socket socket = serverSocket.accept(); //server对象接收的消息存入到Socket对象内
new Thread(new Server_listen(socket)).start();
new Thread(new Servlet_send(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 监听通信 需要实现Runnable接口实现多线程。
* 在监听或者发送的类中都要声明局部变量Socket对象
* 并且通过构造函数将socket对象传入并赋值给Socket声明
*/
class Server_listen implements Runnable{
private Socket socket;
Server_listen(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
while(true){
System.out.println(inputStream.readObject());
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Servlet_send implements Runnable{
private Socket socket;
Servlet_send(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
/**
* 发送消息用ObjectOutputStrearm对象 并将建立连接的soket.getOutputStream()传入
* 相反的如果是listen类那需要传入Input对象监听
*/
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("请输入要发送的内容");
String string = scanner.nextLine();
JSONObject object = new JSONObject();
object.put("type","chat");
object.put("msg",string);
outputStream.writeObject(object);
outputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client端:
public class Client {
private static Socket socket;
private static boolean connection_state = false;
public static void main(String[] args) {
connect();
System.out.println("客户端开始运行....");
if (connection_state){
new Thread(new Client_listen(socket)).start();
new Thread(new Client_send(socket)).start();
}
}
private static void connect(){
try {
socket = new Socket("127.0.0.1",9999);
connection_state = true;
} catch (IOException e) {
e.printStackTrace();
connection_state = false;
}
}
}
class Client_listen implements Runnable{
private Socket socket;
Client_listen(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
while (true){
try {
System.out.println("请输入要发送的内容");
System.out.println(inputStream.readObject());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Client_send implements Runnable{
private Socket socket;
Client_send(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
Scanner scanner = new Scanner(System.in);
while(true){
String string = scanner.nextLine();
JSONObject object = new JSONObject();
object.put("type","chat");
object.put("msg",string);
outputStream.writeObject(object);
outputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
第二版:增加心跳功能
注意事项:心跳实现了监听中不断向服务器发包的操作,理论上是完善了通信的功能,但是目前这个第二版中有些try/catch写的比较乱,位置不对导致逻辑有时候不是很正常,需要进一步调整,由于时间原因先搞这些。接下来的只需要调整逻辑和顺序就可以了。
实现效果:
客户端:
package socket;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
private static Socket socket;
public static boolean connection_state = false;
private static ObjectOutputStream oos;
public static void main(String[] args) {
connect();
}
private static void connect(){
try {
socket = new Socket("127.0.0.1",9999);
connection_state = true;
System.out.println("客户端开始运行....");
if (connection_state){
try {
oos = new ObjectOutputStream(socket.getOutputStream());
new Thread(new Client_listen(socket)).start();
new Thread(new Client_send(socket,oos)).start();
new Thread(new Client_heart(socket,oos)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
connection_state = false;
}
}
public static void reconnect(){
while (!connection_state){
connect();
try {
Thread.sleep(3000);
System.out.println("正在进行重新链接...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Client_listen implements Runnable{
private Socket socket;
Client_listen(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
while (true){
try {
System.out.println("请输入要发送的内容");
System.out.println(inputStream.readObject());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Client_send implements Runnable{
private Socket socket;
private ObjectOutputStream oos;
Client_send(Socket socket,ObjectOutputStream oos){
this.socket = socket;
this.oos=oos;
}
@Override
public void run() {
try {
//ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
Scanner scanner = new Scanner(System.in);
while(true){
String string = scanner.nextLine();
JSONObject object = new JSONObject();
object.put("type","chat");
object.put("msg",string);
oos.writeObject(object);
oos.flush();
}
} catch (IOException e) {
try {
socket.close();
Client.connection_state=false;
Client.reconnect();
} catch (IOException ex) {
ex.printStackTrace();
}
e.printStackTrace();
}
}
}
//心跳包类
class Client_heart implements Runnable{
private Socket socket;
private ObjectOutputStream oos;
Client_heart(Socket socket,ObjectOutputStream oos){
this.socket=socket;
this.oos = oos;
}
@Override
public void run() {
try {
System.out.println("心跳包线程已启动....");
// ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
while (true){
Thread.sleep(5000);
JSONObject object = new JSONObject();
object.put("type","heart");
object.put("msg","心跳包");
oos.writeObject(object);
oos.flush();
}
} catch (IOException e) {
e.printStackTrace();
try {
socket.close();
Client.connection_state=false;
Client.reconnect();
} catch (IOException ex) {
ex.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
服务端:
package socket;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static void main(String[] args) {
System.out.println("Socket服务器开始运行...");
try {
ServerSocket serverSocket = new ServerSocket(9999);
while(true){
Socket socket = serverSocket.accept(); //server对象接收的消息存入到Socket对象内
new Thread(new Server_listen(socket)).start();
new Thread(new Servlet_send(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 监听通信 需要实现Runnable接口实现多线程。
* 在监听或者发送的类中都要声明局部变量Socket对象
* 并且通过构造函数将socket对象传入并赋值给Socket声明
*/
class Server_listen implements Runnable{
private Socket socket;
Server_listen(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
while(true){
//System.out.println(inputStream.readObject());
Object o = inputStream.readObject();
String s = o.toString();
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Servlet_send implements Runnable{
private Socket socket;
Servlet_send(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
/**
* 发送消息用ObjectOutputStrearm对象 并将建立连接的soket.getOutputStream()传入
* 相反的如果是listen类那需要传入Input对象监听
*/
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("请输入要发送的内容");
String string = scanner.nextLine();
JSONObject object = new JSONObject();
object.put("type","chat");
object.put("msg",string);
outputStream.writeObject(object);
outputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
借鉴视频资料:Socket长连接通信