简易socket通信代码

发布时间 2023-09-23 11:30:09作者: RTH030

 

源代码

1,服务端

package socket.ab;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server {
	//创建集合对象
	public static List<MyChannel> list=new ArrayList<MyChannel>();
	public static void main(String[] args) {
		try {
			System.out.println("服务器开始运行");
			ServerSocket serverSocket=new ServerSocket(8080);
			while(true) {
				Socket socket=serverSocket.accept();//接收客户请求
				
				//一个客户机与服务器通信
				//new Thread(new Listen(socket)).start();
				//new Thread(new Send(socket)).start();
				
				//服务器用于交换消息,创建线程类对象
				MyChannel channel=new MyChannel(socket);
				//添加到集合
				list.add(channel);
				if(list != null) {
					System.out.println("服务器收到"+channel+"连接");
				}
				
				new Thread(channel).start();
				
			}
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

  2,集合对象

package socket.ab;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.List;

public class MyChannel implements Runnable{
	private Socket socket;
	private boolean flag=true;
	private ObjectInputStream ois;
	private ObjectOutputStream oos;
	//初始化
	public MyChannel(Socket socket){
		this.socket=socket;
		try {
			ois=new ObjectInputStream(socket.getInputStream());//获取输入流
			oos=new ObjectOutputStream(socket.getOutputStream());//获取输出流
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
			flag=false;
			try {
				socket.close();
			} catch (IOException e1) {
				// TODO 自动生成的 catch 块
				e1.printStackTrace();
			}
		}
	}
	//接收数据方法
	private String receive(){
		String str="";
		try {
			str=ois.readUTF();
			if(str.equals("我是心跳包")) {
				System.out.println(str);
			}
		} catch (IOException e) {
			System.out.println("断开连接");
			flag=false;
			try {
				socket.close();
			} catch (IOException e1) {
				Server.list.remove(this);
			}
		}
		return str;
	}
	//发送数据方法
	private void send(String str) {
		if(str!=null&&str.length()!=0) {
			if(!str.equals("我是心跳包")) {
				try {
					oos.writeUTF(str);
					oos.flush();
				} catch (IOException e) {
					flag=false;
					try {
						socket.close();
//						Server.list.remove(this);
					} catch (IOException e1) {
//						Server.list.remove(this);
					}
				}
			}
		}
	}
	//转发
	private void sendOther() {
		String str=this.receive();
		List<MyChannel> list=Server.list;
		if(list.size()>1) {
			for(MyChannel other :list) {
				if(other==this) {
					continue;//不发给自己
				}
				other.send(str);
			}
		}
	}
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		while(flag) {
			//this.send(receive());
			sendOther();
		}
	}

}

  3,send方法

package socket.ab;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Send implements Runnable{
	private Socket socket;
	private ObjectOutputStream oos;
	public static String name="";
	Send(Socket socket,String name,ObjectOutputStream oos){
		this.socket=socket;
		Send.name=name;
		this.oos=oos;
	}
	String str="";
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		try {
			while(true) {
					Thread.sleep(1000);
					oos.writeUTF(Frame.text);
					oos.flush();
					Frame.text="";
			}
		} catch (IOException | InterruptedException e) {
			System.out.println("发送失败");
		}
	}
	
}

  4,listen方法

package socket.ab;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;

public class Listen implements Runnable{
	private Socket socket;
	//初始化
	Listen(Socket socket){
		this.socket=socket;
	}
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		try {
			//获取输入流
			ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
			while(true) {
				String read=ois.readUTF();
				Frame.jtx.append(Frame.date()+"\n"+"收到"+read+"\n");
//				System.out.println("收到"+ois.readUTF());
			}
		} catch (IOException e) {
			System.out.println("接收失败");
			Client.connet_state=false;
			Client.reconnet();
		}finally {
			try {
				socket.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
	}
}

  5,客户端

package socket.ab;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
	private static Socket socket;
	private static ObjectOutputStream oos;
	public static boolean connet_state=false;
	public static String name=Frame.tit;
//	static String[] arrays=new String[5];
	
	public static void main(String[] args) {
		new Frame();
		System.out.println(name+"连接到服务器");
		connet();
		if(connet_state) {
			try {
				oos=new ObjectOutputStream(socket.getOutputStream());
				new Thread(new Listen(getSocket())).start();
				new Thread(new Send(getSocket(),name,oos)).start();
				new Thread(new HeartBeat(getSocket(),oos)).start();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	private static void connet() {
		try {
			setSocket(new Socket("127.0.0.1",8080));
			connet_state=true;
		} catch (UnknownHostException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
			connet_state=false;
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
			connet_state=false;
		}
	}
	public static void reconnet() {
		while(!connet_state) {
			System.out.println("尝试重新连接...");	
			try {
				connet();
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(connet_state) {
			try {
				oos=new ObjectOutputStream(socket.getOutputStream());
				new Thread(new Listen(getSocket())).start();
				new Thread(new Send(getSocket(),name,oos)).start();
				new Thread(new HeartBeat(getSocket(),oos)).start();
				System.out.println("重连成功");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public static Socket getSocket() {
		return socket;
	}
	public static void setSocket(Socket socket) {
		Client.socket = socket;
	}
}

  6,界面显示

package socket.ab;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;

public class Frame extends java.awt.Frame implements Runnable{
	public static JTextArea jtx=new JTextArea(200,150);
	public static TextField tf=new TextField(30);
	public Frame() {
		initFrame();
		initEventListner();
	}
	public static String text="";
	public static String tit="用户"+new Random().nextInt(900)+100;
	public static String tit2=tit;
//	public static String getTit() {
//		return tit;
//	}
	public static boolean sendflag=true;
//	public static String getText() {
//		return text;
//	}
	private void initFrame() {
		setTitle(tit);
		setSize(600, 500);
		setLocation(new Random().nextInt(500)+100, new Random().nextInt(900)+100);
		setResizable(false);
		Panel p=new Panel();
		
		setLayout(new BorderLayout());
		//滚动条
		JScrollPane j=new JScrollPane();
		j.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		j.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
//		JTextArea jtx=new JTextArea(200,150);
		jtx.setFocusable(false);
		j.setViewportView(jtx);
		add(j,BorderLayout.CENTER);
		p.setLayout(new FlowLayout());
		add(p,BorderLayout.SOUTH);
		
		Button btn=new Button("发送");
		
		tf.requestFocus();
		p.add(tf);
		p.add(btn);
		btn.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO 自动生成的方法存根
//				if(text!=null && !text.trim().equals("")) {
					text=Send.name+":"+tf.getText();
					jtx.append(date()+"\n");
					jtx.append("我发送了:"+tf.getText()+"\n");
					sendflag=true;
					tf.setText("");
//				}
			}
		});
		
		setVisible(true);
		repaint();
		
	}
	public static String date() {
		Date time=new Date();
		SimpleDateFormat format=new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
		return "----------"+format.format(time);
		
	}
	private void initEventListner() {        
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
                System.exit(0);
           }
        });
    }
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		new Frame();

	}
}

  7,心跳包测试

package socket.ab;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class HeartBeat implements Runnable{
	private Socket socket;
	private ObjectOutputStream oos;
	public static String heart="我是心跳包";
	public HeartBeat(Socket socket,ObjectOutputStream oos){
		this.socket=socket;
		this.oos=oos;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("心跳包线程已启动...");
		try {
			while(true) {
				Thread.sleep(5000);
				oos.writeUTF(heart);
//				oos.flush();
			}
			
		} catch (InterruptedException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Client.connet_state=false;
			Client.reconnet();
		}
	}

}