这是老师布置的一次上机作业,这几天一直在学习Web的内容,有些不常用的工具都忘了。
我捡起来的还算快,前前后后大概花了三,四个小时写出来了一版逻辑清晰一点的多线程聊天室。
一.包的结构
二.客户端
public class Client {
//author pzh hueedu
/*
* 任务:
* 1.为每一个Client用户创建一个Socket
* 2.开启发送线程
* 3.开启接受线程
*/
public static void main(String[] args) throws Exception {
Socket ss = new Socket(InetAddress.getLocalHost(),50000);
new Thread(new ReceiceMessage(ss)).start();
new Thread(new SendMessage(ss)).start();
}
}
public class SendMessage implements Runnable {
//author pzh hueedu
private BufferedWriter bw = null;
public SendMessage(Socket s){
try {
bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void Writer(){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String test = null;
String result = null;
try {
while((test=br.readLine())!=null){
result = test;
bw.write(result);
bw.newLine();
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while(true){
Writer();
}
}
}
public class ReceiceMessage implements Runnable {
//author pzh hueedu
/*
* 拿到Socket的对应的接受流 死循环接受数据并打印在控制台上
*/
private Socket s;
private BufferedReader br = null;
public ReceiceMessage(Socket s) {
try {
this.s = s;
this.br = new BufferedReader(new InputStreamReader(s.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public String recive(){//函数目的 把收到一行数据返回
String test = null;
String result = null;
try {
while((test = br.readLine()) != null){
result = test;
System.out.println(s.getInetAddress()+"接受到了服务器端数据"+result);
}
} catch (IOException e) {e.printStackTrace();}
return result;
}
public void run() {//死循环 用于输出接受到的数据
while(true){
recive();
}
}
}
三 服务器端
public class Server {
//author pzh hueedu
/*
* 任务 为每一个接受到的客户创建一个进程,进入Dispatcher全体进行转发。
*/
private static List<Socket> socketlist = Collections.synchronizedList(new ArrayList<Socket>());
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(50000);
while(true){
Socket s = ss.accept();//阻塞式方式。
socketlist.add(s);
System.out.println(socketlist);
new Thread(new DispatcherMessage(s,socketlist)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.List;
public class DispatcherMessage implements Runnable{
//author pzh hueedu
private Socket s = null;
private BufferedReader br = null;
private List<Socket> socketlist = null;
public DispatcherMessage(Socket s,List<Socket> socketlist) {
this.socketlist = socketlist;
this.s = s;
try {
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void DispathcherMessage(){
String test = null;
String result = null;
try {
while((test=br.readLine())!=null){
for(Socket allsocket:socketlist){
if(!s.equals(allsocket)){
result = test;
System.out.println(result+"服务器接受端测试");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(allsocket.getOutputStream()));
bw.write(result);
bw.newLine();
bw.flush();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while(true){
DispathcherMessage();
}
}
}
三.程序运行截图
四.总结
要对写的程序有一个整体的把握,例如在创建客户时明确要给客户开启接受和发送进程,在服务器端接受到一个客户的消息,要对所有客户进行转发。这就需要每一个客户都要有一个转发线程。在写程序时最好把该考虑的都思考完了写,否则写的逻辑不会很清晰。