JavaSE版聊天室项目

JavaSE聊天室小项目

 

使用TCP编程实现客户端和服务器端的不断交互

 

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 *   客户端
 * */
public class ChatRoomClient {

	public static void main(String[] args) {
		
		try {
			//创建Socket对象
			Socket s = new Socket("127.0.0.1",12345);
			
			//获取客户端通道的输出和输入流
			InputStream in = s.getInputStream();
			OutputStream out = s.getOutputStream();
			
			//创建键盘录入对象
			Scanner sc = new  Scanner(System.in);
			
			//客户端不断的发送消息
			while(true) {
				System.out.println("请输入消息:");
				String msg = sc.nextLine();
				//使用输出流发送过去
				out.write(msg.getBytes());
				
				//客户端读取服务器发送的消息
				byte [] bys = new byte [1024];
				int len = in.read(bys);
				String msgStr = new String(bys, 0, len);
				System.out.println(msgStr);
			}
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

 

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * 服务器端
 * */
public class ChatRoomServer {

	public static void main(String[] args) {
		
		try {
			//创建服务器端Socket对象
			ServerSocket ss = new ServerSocket(12345);
			//监听客户端
			Socket s = ss.accept();
			//获取服务器端通道的输出和输入流
			InputStream in = s.getInputStream();
			OutputStream out = s.getOutputStream();
			
			//创建键盘录入对象
			Scanner sc = new  Scanner(System.in);
			
			//服务器端不断的读取消息和回复消息
			while(true) {
				
				//读消息
				byte [] bys = new byte [1024];
				int len = in.read(bys);
				String msg = new String(bys, 0, len);
				System.out.println(msg);
				//回复消息
				System.out.println("请回复消息:");
				String msgStr = sc.nextLine();
				out.write(msgStr.getBytes());
			}	
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


这样做有问题,客户端和服务器端的读发消息都在一个线程,可能会出现互相等待的问题

 

 

改进:将读消息放在子线程里面(规定)

客户端

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
 * 客户端
 * @author dreamer_96
 */
public class ChatRoomClient {

	public static void main(String[] args) {
		
		try {
			//创建Socket对象
			Socket s = new Socket("127.0.0.1",12345);
			
			//获取客户端通道的输出和输入流
			InputStream in = s.getInputStream();
			OutputStream out = s.getOutputStream();
			
			//创建键盘录入对象
			Scanner sc = new  Scanner(System.in);
			
			//开启读消息子线程
			ClientThread ct = new ClientThread(in);
			ct.start();
			//客户端不断的发送消息
			while(true) {
				System.out.println("请输入消息:");
				String msg = sc.nextLine();
				//使用输出流发送过去
				out.write(msg.getBytes());
			}	
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

客户端读消息子线程

import java.io.IOException;
import java.io.InputStream;
/**
 * 客户端读取消息的子线程
 * @author dreamer_96
 */
public class ClientThread extends Thread {

	private InputStream in ;

	public ClientThread(InputStream in) {
		this.in = in;
	}

	@Override
	public void run() {
		
		try {
			while(true) {
				//客户端不断读取服务器发送的消息
				byte [] bys = new byte [1024];
				int len = in.read(bys);
				String msgStr = new String(bys, 0, len);
				System.out.println(msgStr);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
}


服务器端

 

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * 服务器端
 * @author dreamer_96
 */
 
public class ChatRoomServer {

	public static void main(String[] args) {
		
		try {
			//创建服务器端Socket对象
			ServerSocket ss = new ServerSocket(12345);
			//监听客户端
			Socket s = ss.accept();
			//获取服务器端通道的输出和输入流
			InputStream in = s.getInputStream();
			OutputStream out = s.getOutputStream();
			
			//创建键盘录入对象
			Scanner sc = new  Scanner(System.in);
			
			//开启子线程
			ServerThread st = new ServerThread(in);
			st.start();
			//服务器端不断的读取消息和回复消息
			while(true) {
				//回复消息
				System.out.println("请回复消息:");
				String msgStr = sc.nextLine();
				out.write(msgStr.getBytes());
			}	
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


服务器端读消息子线程

 

import java.io.IOException;
import java.io.InputStream;

/**
 * 服务器端读取消息的子线程
 * @author dreamer_96
 */
public class ServerThread extends Thread {

	private InputStream in;
	
	public ServerThread(InputStream in) {
		this.in= in ;
	}

	@Override
	public void run() {
		try {
			while(true) {
				//读取客户端发送的消息
				byte [] bys = new byte [1024];
				int len = in.read(bys);
				String msg = new String(bys, 0, len);
				System.out.println(msg);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	
	}	
}


使用ArrayList集合存储Socket对象

 

服务器端

 

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * 服务器端
 * @author dreamer_96
 */
 
public class ChatRoomServer {

	public static void main(String[] args) {
		
		try {
			//创建服务器端Socket对象
			ServerSocket ss = new ServerSocket(12345);
			
			//创建ArrayList集合;分别保存每个通道内的Socket对象
			ArrayList<Socket> list = new ArrayList<Socket>();
			System.out.println("等待客户端连接,请稍后....");
			
			int i = 1;
			while(true) {
				
				//监听客户端
				Socket s = ss.accept();
				System.out.println("第"+(i++)+"个客户端已连接");
				//服务器一监听到客户端,就跳添加到集合中
				list.add(s);
				//获取服务器端通道的输出和输入流
				InputStream in = s.getInputStream();
				OutputStream out = s.getOutputStream();
				
				//开启子线程
			//	ServerThread st = new ServerThread(in);
				ServerThread st = new ServerThread(s,list);
				st.start();
			}
			
			/*//创建键盘录入对象
			Scanner sc = new  Scanner(System.in);
			//服务器端不断的读取消息和回复消息
			while(true) {
				//回复消息
				System.out.println("请回复消息:");
				String msgStr = sc.nextLine();
				out.write(msgStr.getBytes());
			}*/	
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


服务器端读消息子线程

 

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;

/**
 * 服务器端读取消息的子线程
 * @author dreamer_96
 */
public class ServerThread extends Thread {

	/*private InputStream in;
	
	public ServerThread(InputStream in) {
		this.in= in ;
	}*/

	private Socket s;
	private ArrayList<Socket> list;
	
	public ServerThread(Socket s, ArrayList<Socket> list) {
		this.s = s;
		this.list = list;
	}

	@Override
	public void run() {
		try {
			//获取通道内的输入输出流		
			InputStream in = s.getInputStream();
			OutputStream out = s.getOutputStream();
			while(true) {
				//读取客户端发送的消息
				byte [] bys = new byte [1024];
				int len = in.read(bys);
				String msg = new String(bys, 0, len);
				//msg现在的格式:  接收者:消息内容:发送者
				System.out.println(msg);
				
				//将消息拆分
				String[] msgs = msg.split(":");
			
				Socket socket = list.get(Integer.parseInt(msgs[0]));
				//获取输出流,写过去
				OutputStream os = socket.getOutputStream();
				os.write((msgs[2]+"对你说"+msgs[1]).getBytes());
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	
	}	
}


客户端不变,这样做依旧有缺点,我们要遵循开发规则 “高内聚,低耦合” ;所以我们使用HashMap集合添加用户并且增加服务器保存用户的子线程SaveUserThread

 

 

 

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: JavaSE项目列表是指在JavaSE平台上开发的各种项目的清单。JavaSE是指Java标准Java Standard Edition),它是一种完整的Java开发平台,提供了一系列基本的功能和API,用于开发桌面应用程序和小型服务器应用程序。 在JavaSE项目列表中,常见的项目包括: 1. 图形用户界面(GUI)应用程序:JavaSE提供了丰富的图形库,使开发者可以轻松地创建交互式窗口应用程序。比如JavaFX和Swing等库可以用来开发各种图形界面项目。 2. 命令行工具:使用JavaSE,可以开发各种命令行工具,用于完成各种任务,如文件处理、数据分析等。 3. 小型服务器应用程序:JavaSE提供了一些网络相关的API,如Socket编程,可以用于开发小型服务器应用程序,如聊天程序、文件传输程序等。 4. 数据库应用程序:JavaSE提供了一些用于数据库连接和操作的API,可以用于开发各种数据库应用程序。可以使用JDBC来连接各种不同的数据库,进行数据的增删改查等操作。 5. 网络应用程序:使用JavaSE,可以开发各种网络应用程序,如Web服务器、Web应用程序等。可以使用Java提供的HttpURLConnection类来发送HTTP请求和接收HTTP响应,同时也可以使用Java的Servlet API来开发服务器端的应用程序。 总之,JavaSE项目列表非常广泛,涵盖了各种类型的应用程序开发。JavaSE通过提供丰富的类库和API,为程序员提供了一种强大而灵活的开发平台,使得开发各种应用程序变得更加简便和高效。 ### 回答2: JavaSE项目列表是指一种使用Java标准JavaSE)开发的项目的列表。JavaSEJava平台的一个基础本,它提供了一系列的API和工具,用于开发应用程序。 JavaSE项目的列表可以包括各种类型的应用程序,例如桌面应用程序、命令行工具、小型的服务器端应用等等。以下是一些常见的JavaSE项目示例: 1. 图书管理系统:这是一个桌面应用程序,用于管理图书馆的图书和借阅记录。通过JavaSE提供的Swing或JavaFX图形界面库,可以实现用户界面和交互功能。 2. 邮件发送工具:这是一个命令行工具,用于通过SMTP协议发送电子邮件。JavaSE提供的JavaMail API可以用于构建和发送电子邮件。 3. 文件压缩工具:这是一个命令行工具,用于压缩和解压缩文件。JavaSE提供的java.util.zip包可以用于处理ZIP格式的文件压缩。 4. 网络聊天室:这是一个网络应用程序,用于实现即时的文本聊天功能。JavaSE提供的Socket和ServerSocket类可以用于实现网络通信。 5. 学生信息管理系统:这是一个桌面应用程序,用于管理学生的基本信息、课程选修和成绩录入。通过JavaSE提供的数据库访问API(如JDBC),可以实现与数据库的连接和数据持久化。 这些只是一些示例,实际上JavaSE可以用于开发各种各样的项目。通过使用JavaSE的API和工具,开发人员可以灵活地构建出符合需求的应用程序。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值