简易聊天室的实现。

一个简单的消息群里的聊天室功能,虽然功能不强大,主要是为了给初学者梳理梳理一下思路。希望能够帮到有需要的人,大家一同共同学习,互相帮助。’

package mysocket;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
 * 客户端
 * @author DELL
 *
 */
public class Client {
	/*
	 * Socket 套接字
	 * 封装了TCP协议连接和通讯的细节,使用它与远端计算检疫连接后可以通过两条流来实现
	 * 相互的数据交换
	 */
	private Socket socket;
	//主方法
	public static void main(String[] args) {
		Client client = new Client();
		client.start();
	}
	//构造方法,初始化程序
	public Client() {
		/*
		 * 实例化Socket
		 * 实例Socket需要传入两个参数
		 * Socket(String host, int port)
		 * 1:服务端计算机地址信息(IP)
		 * 2:服务端程序申请的服务端口
		 * 
		 * 实例化过程就是与服务端建立连接的过程,
		 * 若指定的IP地址与端口无效时,这里实例化
		 * 就会抛出异常。因此我们在实例化的同时要处理
		 * 异常。
		 * 
		 */
		try {
			System.out.println("正在连接服务端...");
			socket = new Socket("localhost",8088);
			System.out.println("服务端连接成功!");
		} catch (Exception e) {
		}
	}
	//运行程序的方法
	public void start() {
		/*
		 * 这里执行与服务端进行消息交互的方法。
		 * 如果希望向服务端发送消息我们需要通过Socket
		 * OutputStream  getOnputStream()
		 * 方法获取输出流
		 */
		try {
			/*
			 * 串联一个流连接,提升效率
			 */
			OutputStream out = socket.getOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
			BufferedWriter bw = new BufferedWriter(osw);
			PrintWriter pw = new PrintWriter(bw,true);//此处注意参数true,若不添加此方法我们需要频繁调用flush方法来保证消息的及时性。
			Scanner scan = new Scanner(System.in);
			while(true) {
				String line = scan.nextLine();
				pw.println(line);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
package mysocket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * 服务端
 * @author DELL
 *
 */
public class Server {
	/*
	 * java.net.ServerSocket
	 * 运行在服务端的ServerSocket主要有两个作用
	 * 1:向系统申请服务端口,客户端就是通过这个端口与服务端建立连接的
	 * 2:监听服务端口,一旦客户端通过该端口连接则马上会实例化一个
	 * Socket与之反应。服务端就可以通过这个Socket与客户端进行交互了。
	 * 
	 * 如果把Socket比喻为电话,那么ServerSocket可以想象为是总机。
	 */
	private ServerSocket server;
	public static void main(String[] args) {
		Server server = new Server();
		server.start();
	}
	//构造方法,初始化程序
	public Server() {
		try {
			/*
			 * 实例化ServerSocket的同时要制定服务端口。
			 * 当该端口已经被系统其它程序所使用时,会抛出地址被占用的异常。
			 * 因此我们也需要使用异常处理机制处理一下。
			 */
			System.out.println("正在启动服务端...");
			server = new ServerSocket(8088);
			System.out.println("服务端启动完毕!");
		} catch (IOException e) {
		}
	}
	public void start() {
		while(true) {
			/*
			 * ServerSocket提供的方法:
			 * Socket accept();
			 * 该方法是一个阻塞方法,执行后服务端开始监听服务端口,知道一个客户端连接为止,
			 * 这时该方法会返回一个Socket实例,通过该实例即可以与客户端进行通讯了。
			 * 每次调用该方法都会导致服务端阻塞,等待一个客户端的连接。
			 */
			try {
				System.out.println("正在等待客户端连接...");
				Socket socket = server.accept();
				//此时在等待一个窗口为8088的客户端连接,我们要实现群聊效果,因此需要使用到多线程。
				MyRunnable client = new MyRunnable(socket);
				Thread thread = new Thread(client);
				thread.start();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		
	}
}
class MyRunnable implements Runnable{
	private Socket socket;
	String host;
	public MyRunnable(Socket socket) {
		this.socket = socket;
		/*
		 * getInetAddress()返回对象包含远程计算机的IP地址
		 * InetAddress.getHostAddress()返回对象与该地址的文本表示。
		 */
		InetAddress address = socket.getInetAddress();
		host = address.getHostAddress();
		System.out.println("IP:"+host+"连接成功!");
	}
	public void run() {
		try {
			//在这里我也同样通过Socket提供的方法实现与客户端的交互
			InputStream in = socket.getInputStream();
			InputStreamReader isr = new InputStreamReader(in,"utf-8");
			BufferedReader br = new BufferedReader(isr);
			String str = null;
			/*
			 * br.readLine()读取客户端发送过来的一行字符串的操作中
			 * 当客户端断开连接时,客户端系统不同
			 * 这里的表现也不同
			 * 通常windows的客户端断开时,readLine方法会直接抛出异常
			 * linux的客户端断开连接时,readLine方法的返回值通常为null
			 */
			while((str = br.readLine())!=null) {
				System.out.println("IP:"+host+"说:"+str);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
发布了17 篇原创文章 · 获赞 18 · 访问量 1040

猜你喜欢

转载自blog.csdn.net/qq_40409260/article/details/89366262