Java网络编程,模拟QQ群聊功能
一、网络编程知识点简介:
1.C/S架构:Client客户端/Server服务器:
涉及到的应用:桌面的应用软件,QQ,王者荣耀涉及到的技术:Socket网络编程
2.网络:
各个孤立的工作站或主机相连在一起,从而达到资源共享和通信的目的
2.1 网络分为局域网和广域网:
局域网:
在局域网里可以实现数据的共享优点:规模小,容易搭建,传输速度快比如:公司的局域网,学校宿舍里的网络
广域网:
因特网就是世界范围内最大的广域网(WWW)
3.网络协议:
****TCP(Transmis Control Protocol,传输控制协议)—>(面向连接)****UDP(User Datagram Protocol,用户数据报协议)—>(面向非连接)
4.端口和套接字:
端口(port):可以认为是设备与外界通信交流的出口,范围是0-65535之间的整数Java提供了IP地址的封装类InetAddress,它位于java.net包中,主要封装ip地址
二、题目要求:
实现QQ群聊功能:
客户端之间的聊天,本质是客户端发送一条消息后,由服务器转发到另外的所有客户端
三、简述步骤:
1.在服务器TCPServer类中定义List集合用来存放所有连接进来的客户端2.ClientThread的run方法中,当构建好PrintWriter对象后,将对象加入到List集合中3.在接收客户端消息的地方,调用sendMsg方法,将消息发送给除了自己以外的所有的客户端4.完成sendMsg方法
四、代码实现:
1.创建客户端类:
1.1 封装打开客户端的方法
public class TCPClient01 {
public void open() {
try {
Socket client
= new Socket("localhost",9999);
System
.out
.println("连接服务器成功!");
InputStream is
= client
.getInputStream();
new ReadFromServer(is
).start();
OutputStream os
= client
.getOutputStream();
new WriteToServer(os
).start();
} catch (Exception e
) {
e
.printStackTrace();
}
}
public static void main(String
[] args
) {
TCPClient01 client
= new TCPClient01();
client
.open();
}
}
1.2 封装读取服务器发送消息的线程:
class ReadFromServer extends Thread{
InputStream is
;
public ReadFromServer(InputStream is
) {
this.is
= is
;
}
@Override
public void run() {
BufferedReader br
= new BufferedReader(new InputStreamReader(is
));
String line
= null
;
try {
while((line
=br
.readLine())!=null
){
System
.out
.println(line
);
}
br
.close();
} catch (IOException e
) {
e
.printStackTrace();
}
}
}
1.3 封装客户端向服务器发送消息的线程:
class WriteToServer extends Thread{
OutputStream os
;
public WriteToServer(OutputStream os
) {
super();
this.os
=os
;
}
@Override
public void run() {
Scanner key
= new Scanner(System
.in
);
PrintWriter pw
= new PrintWriter(os
);
while(true) {
String line
= key
.nextLine();
pw
.println(line
);
pw
.flush();
}
}
}
2.创建服务器类:
2.1创建并启动服务器的方法:
public class TCPServer01 {
Map
<String,PrintWriter> allout
;
public void start() {
allout
= new HashMap<String,PrintWriter>();
try {
ServerSocket server
= new ServerSocket(9999);
System
.out
.println("服务器启动成功,等待用户接入...");
while(true) {
Socket client
= server
.accept();
System
.out
.println("有客户接入,客户的IP为:"+client
.getInetAddress());
new ClientThread(client
,allout
).start();
}
} catch (IOException e
) {
e
.printStackTrace();
}
}
public static void main(String
[] args
) {
TCPServer01 server
= new TCPServer01();
server
.start();
}
}
2.2 向客户端发送消息,接收客户端发送过来的消息
class ClientThread extends Thread{
Socket client
;
Map
<String,PrintWriter> allout
;
public ClientThread(Socket client
, Map
<String, PrintWriter> allout
) {
super();
this.client
= client
;
this.allout
= allout
;
}
@Override
public void run() {
try {
OutputStream out
= client
.getOutputStream();
PrintWriter pw
= new PrintWriter(out
);
pw
.println("~~~欢迎来到云轩棋牌聊天室~~~~");
pw
.println("请先输入您的聊天昵称:");
pw
.flush();
InputStream in
= client
.getInputStream();
BufferedReader br
= new BufferedReader(new InputStreamReader(in
));
String name
= br
.readLine();
allout
.put(name
, pw
);
String line
= null
;
while((line
=br
.readLine())!=null
){
sendMsg(name
+"说:"+line
,pw
);
}
br
.close();
} catch (IOException e
) {
e
.printStackTrace();
}
}
2.3 向其他所有的客户端发送消息的方法:
private void sendMsg(String line
, PrintWriter pw
) {
Set
<String> names
= allout
.keySet();
for(String name
:names
){
PrintWriter p
= allout
.get(name
);
if(p
!= pw
){
p
.println(line
);
p
.flush();
}
}
}
}
五、运行结果展示:
*温馨提示:运行时,首先启动服务器,然后启动客户端哟
结语:技术无他,唯有熟尔。知其然,也知其所以然;不要着急,你想要的,岁月都会给你。