Java聊天室搭建
2016-01-11 12:28
351 查看
做这个项目前需要先做好分析:
聊天室分为两个模块,服务器和客户端。
服务器主要实现逻辑是:客户端第一次进入聊天室打印欢迎日志、接收客户端的消息打印在聊天室中、群发给其他用户、判断私聊的条件。
客户端主要实现逻辑是:初始化信息、发送消息给服务器、接收来自服务器的消息。
项目从简单版本往上写,逐步增加功能:
第一个版本:通过TCP搭建服务器和客户端,一个客户端上线服务器就打印一条上线提示。
第二个版本:客户端发送一条消息,服务器接收一条,并反馈一条已接收的信息给客户端。
第三个版本:通过多线程使客户端能不断给服务器发送消息,服务器也能不断回复客户端的信息。
第四个版本:多个客户端开启时,自身发送的消息由服务器发给其他所有客户端,在聊天室中打印出以客户端姓名为前缀的每个人发出的消息。
第五个版本:判断哪些是私聊的信息,私聊信息既不打印在聊天室中也只会发送给当前用户的私聊对象。完善代码。
服务器代码:来一个客户端就开启一个服务器线程。具体逻辑放在线程中完成。
public
class
Server {
public
static
void
main(String[]
args)
throws
IOException {
List<
ServerThread>
list
=
new
ArrayList<ServerThread>();
[align=left]//判断私聊时需要知道发送给哪个客户端,所以把为每一个客户端服务的线程放入一个集合中。以此来遍历所以客户端。[/align]
ServerSocket
serverSocket
=
new
ServerSocket(8080);
while(
true){
Socket
socket
=
serverSocket.accept();
ServerThread serverThread
=
new
ServerThread(socket,list);
[align=left]//开启线程时把当前客户端对应套接字和装有所有serverThread对象的集合传递给为当前客户端服务的线程。[/align]
list.add(
serverThread);
[align=left]//开启一个就往list中添加一个。[/align]
serverThread.start();
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
客户端代码:读入键盘输入数据,发送给服务器,并接收来自服务器的消息。读和写分别使用不同的线程。
public
class
Client {
public
static
void
main(String[]
args)
throws
UnknownHostException, IOException {
Socket
socket
=
new
Socket(
"10.2.155.91", 8080);
[align=left]//通过服务器ip地址和服务器端口号建立与服务器的连接。[/align]
WriterThread
writerThread
=
new
WriterThread(socket);
[align=left]//开启一个写线程发送数据到服务器。[/align]
writerThread.start();
ReaderThread
readerThread
=
new
ReaderThread(socket);
[align=left]//开启一个读线程接收来自服务器的消息。[/align]
readerThread.start();
[align=left] }[/align]
[align=left]}[/align]
服务器线程代码:
public
class
ServerThread
extends
Thread{
private
Socket
socket;
private
BufferedReader
bReader;
private
BufferedWriter
bWriter;
private
List<ServerThread>
list;
private
String
name;
public
ServerThread(Socket
socket,List<ServerThread>
list) {
try
{
this.
socket
=
socket;
this.
list
=
list;
bReader
=
new
BufferedReader(
new
InputStreamReader(socket.getInputStream()));
bWriter
=
new
BufferedWriter(
new
OutputStreamWriter(socket.getOutputStream()));
}
catch
(IOException
e) {
e.printStackTrace();
[align=left] }[/align]
[align=left] }[/align]
public
void
run() {
[align=left] WelcomeChat();[/align]
try
{
while(
true){
String
info
=
bReader.readLine();
if
(info.startsWith(
"@")&&
info.indexOf(
"#") !=-1&&
info.indexOf(
"#")-
info.indexOf(
"@")>1) {
SendByName(
info);
[align=left] }[/align]
else
{
System.
out.println(
name+
"说:"+info
);
SendToOthers(
info);
[align=left] }[/align]
[align=left] }[/align]
}
catch
(IOException
e) {
e.printStackTrace();
[align=left] }[/align]
[align=left] }[/align]
private
void
WelcomeChat() {
try
{
name
=
bReader.readLine();
System.
out.println(
"欢迎"+name
+"进入聊天室"
);
}
catch
(IOException
e1) {
//
TODO
Auto-generated catch block
e1.printStackTrace();
[align=left] }[/align]
[align=left] }[/align]
[align=left]
[/align]
private
void
SendByName(String
info)
throws
IOException {
String
name2
=
info.substring(
info.indexOf(
"@") + 1,
info.indexOf("#"
));
info
=
info.substring(
info.indexOf(
"#")+1);
for
(ServerThread
serverThread
:
list) {
if
(
name2.equals(
serverThread.
name)) {
bWriter
=
new
BufferedWriter(
new
OutputStreamWriter(serverThread.socket
.getOutputStream()));
bWriter.write(
name
+
"悄悄对你说:"
+
info);
bWriter.newLine();
bWriter.flush();
break;
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
private
void
SendToOthers(String
info)
throws
IOException {
for
(ServerThread
serverThread
:
list) {
if
(Thread.
currentThread()!=serverThread)
{
bWriter
=
new
BufferedWriter(
new
OutputStreamWriter(serverThread.socket
.getOutputStream()));
bWriter.write(
name+
"说:"+info
);
bWriter.newLine();
bWriter.flush();
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
聊天室分为两个模块,服务器和客户端。
服务器主要实现逻辑是:客户端第一次进入聊天室打印欢迎日志、接收客户端的消息打印在聊天室中、群发给其他用户、判断私聊的条件。
客户端主要实现逻辑是:初始化信息、发送消息给服务器、接收来自服务器的消息。
项目从简单版本往上写,逐步增加功能:
第一个版本:通过TCP搭建服务器和客户端,一个客户端上线服务器就打印一条上线提示。
第二个版本:客户端发送一条消息,服务器接收一条,并反馈一条已接收的信息给客户端。
第三个版本:通过多线程使客户端能不断给服务器发送消息,服务器也能不断回复客户端的信息。
第四个版本:多个客户端开启时,自身发送的消息由服务器发给其他所有客户端,在聊天室中打印出以客户端姓名为前缀的每个人发出的消息。
第五个版本:判断哪些是私聊的信息,私聊信息既不打印在聊天室中也只会发送给当前用户的私聊对象。完善代码。
服务器代码:来一个客户端就开启一个服务器线程。具体逻辑放在线程中完成。
public
class
Server {
public
static
void
main(String[]
args)
throws
IOException {
List<
ServerThread>
list
=
new
ArrayList<ServerThread>();
[align=left]//判断私聊时需要知道发送给哪个客户端,所以把为每一个客户端服务的线程放入一个集合中。以此来遍历所以客户端。[/align]
ServerSocket
serverSocket
=
new
ServerSocket(8080);
while(
true){
Socket
socket
=
serverSocket.accept();
ServerThread serverThread
=
new
ServerThread(socket,list);
[align=left]//开启线程时把当前客户端对应套接字和装有所有serverThread对象的集合传递给为当前客户端服务的线程。[/align]
list.add(
serverThread);
[align=left]//开启一个就往list中添加一个。[/align]
serverThread.start();
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
客户端代码:读入键盘输入数据,发送给服务器,并接收来自服务器的消息。读和写分别使用不同的线程。
public
class
Client {
public
static
void
main(String[]
args)
throws
UnknownHostException, IOException {
Socket
socket
=
new
Socket(
"10.2.155.91", 8080);
[align=left]//通过服务器ip地址和服务器端口号建立与服务器的连接。[/align]
WriterThread
writerThread
=
new
WriterThread(socket);
[align=left]//开启一个写线程发送数据到服务器。[/align]
writerThread.start();
ReaderThread
readerThread
=
new
ReaderThread(socket);
[align=left]//开启一个读线程接收来自服务器的消息。[/align]
readerThread.start();
[align=left] }[/align]
[align=left]}[/align]
服务器线程代码:
public
class
ServerThread
extends
Thread{
private
Socket
socket;
private
BufferedReader
bReader;
private
BufferedWriter
bWriter;
private
List<ServerThread>
list;
private
String
name;
public
ServerThread(Socket
socket,List<ServerThread>
list) {
try
{
this.
socket
=
socket;
this.
list
=
list;
bReader
=
new
BufferedReader(
new
InputStreamReader(socket.getInputStream()));
bWriter
=
new
BufferedWriter(
new
OutputStreamWriter(socket.getOutputStream()));
}
catch
(IOException
e) {
e.printStackTrace();
[align=left] }[/align]
[align=left] }[/align]
public
void
run() {
[align=left] WelcomeChat();[/align]
try
{
while(
true){
String
info
=
bReader.readLine();
if
(info.startsWith(
"@")&&
info.indexOf(
"#") !=-1&&
info.indexOf(
"#")-
info.indexOf(
"@")>1) {
SendByName(
info);
[align=left] }[/align]
else
{
System.
out.println(
name+
"说:"+info
);
SendToOthers(
info);
[align=left] }[/align]
[align=left] }[/align]
}
catch
(IOException
e) {
e.printStackTrace();
[align=left] }[/align]
[align=left] }[/align]
private
void
WelcomeChat() {
try
{
name
=
bReader.readLine();
System.
out.println(
"欢迎"+name
+"进入聊天室"
);
}
catch
(IOException
e1) {
//
TODO
Auto-generated catch block
e1.printStackTrace();
[align=left] }[/align]
[align=left] }[/align]
[align=left]
[/align]
private
void
SendByName(String
info)
throws
IOException {
String
name2
=
info.substring(
info.indexOf(
"@") + 1,
info.indexOf("#"
));
info
=
info.substring(
info.indexOf(
"#")+1);
for
(ServerThread
serverThread
:
list) {
if
(
name2.equals(
serverThread.
name)) {
bWriter
=
new
BufferedWriter(
new
OutputStreamWriter(serverThread.socket
.getOutputStream()));
bWriter.write(
name
+
"悄悄对你说:"
+
info);
bWriter.newLine();
bWriter.flush();
break;
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
private
void
SendToOthers(String
info)
throws
IOException {
for
(ServerThread
serverThread
:
list) {
if
(Thread.
currentThread()!=serverThread)
{
bWriter
=
new
BufferedWriter(
new
OutputStreamWriter(serverThread.socket
.getOutputStream()));
bWriter.write(
name+
"说:"+info
);
bWriter.newLine();
bWriter.flush();
[align=left] }[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left]}[/align]
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- 小心服务器内存居高不下的元凶--WebAPI服务
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- 运维入门
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序