本次共分为11个版本:
任务1-v1:代码修正
1.定义成员变量套接字
2.在构造方法中初始化
3.start方法处理读写
4.main方法创建对象,调用start方法
----------------------------------------------------------
任务2-v2:
1.控制台一对一对话
2.在客户端实现控制台输入
----------------------------------------------------------
任务3-v3:
1.一个客户端和服务器多次会话
2.客户端使用while循环输入
3.服务器端使用while循环接收数据
--------------------------------------------------------
任务4-v4:实现多线程的服务端
1.服务器端实现线程处理客户端请求
定义线程
private class ClientHandler implements Runnable{
//定义Socket 变量
public ClientHandler(Socket socket){
//初始化成员变量
}
public void run() {
//实现读写功能
}
}
2.让服务可以接受多客户端的请求
------------------------------------------------------------
任务5-v5:实现群聊
1.服务器端
定义存放所有客户端输出流对象的数组
//存放所有的客户端的输出流对象
private PrintWriter[] allOut;
构造方法中初始化
serverSocket = new ServerSocket(8888);
//初始化
allOut = new PrintWriter[0];
在响应客户端数据时,遍历数组的输出流
2.客户端
定义线程,负责接收服务器的响应信息,实现对写分离
---------------------------------------------------------
任务6-v6:实现窗口
任务7-v7:读写对象
1)把客户端和服务器端的输入输出流改为对象的输入输出流
ObjectInputStream和ObjectOutputStream
2)定义工具类
public class Info{
//0表示群聊;1表示上线,2表示下线,3表示私聊
private int type;
private String name;
private String sendInfo;
}
3)客户端发送信息为Info对象,服务器响应信息为Info对象
-------------------------------------------------------------
任务v8-v8:添加登录的窗口,根据登录名称显示用户姓名
--------------------------------------------------------------
任务v9-v9:显示在线列表
1.在Info类中定义存放登录名的数组变量,添加set/get方法
2.在服务器类中定义存放登录名的数组,构造方法中初始化,
run方法中进行数组的扩容
3.客户端发送的type=1,响应对象把登录人的数组传递给响应对象放回给客户端
4.客户端登录成功,发送type=1的请求
5.控制台测试。。。。。
6.在窗口中添加在线列表组件,显示在线人的姓名
---------------------------------------------------------------
任务10-v10:下线
1)添加窗口的关闭处理事件,在关闭窗口的事件处理方法中发送
type= 2的下线请求
2)服务器端代码调整,重新给数组赋值,数组中不包含下线的姓名
把数组返回给客户端
3)客户端的响应信息代码调整,参照上线处理
--------------------------------------------------------------
第十一个任务:单聊
1)在右侧选择单聊的对象,使用list的selected事件处理
//列表的选中事件,(此代码写下窗口事件的后边)
list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
//name表示单聊的那个对象的名字(name声明为成员变量)
name = list.getSelectedValue();
}
});
2)在发送按钮的事件处理方法中进行处理(源代码需要重新调整)
判断name!=null,那么发送type=3的单聊请求
Info info = new Info(3,name,tfName.getText());
否则发送的是群聊。
参考代码如下:
3)在服务器端处理type=3的的请求处理
通过name找到单聊的客户端的输出流;allOut={oos1,oos2}
通过oos找到当前客户的名字 onlines={name1,name2}
响应请求对象Info:
参考代码如下:
4)客户端响应信息处理
同群聊处理
🔺v1:
package com.rjxy.TCP.v1;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 1.定义成员变量套接字
2.在构造方法中初始化
3.start方法处理读写
4.main方法创建对象,调用start方法
* @author 陶沅玱
*
*/
public class Client {
//1.创建套接字对象
private Socket socket;
public Client() {
try {
//实例化套接字对象
socket = new Socket("localhost", 6666);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
//2.对服务器发出请求
OutputStream os = socket.getOutputStream();
//打印流
PrintWriter pw = new PrintWriter(os);
pw.println("hello");
pw.flush();
//3.接受服务器的响应
InputStream is = socket.getInputStream();
//把字节流转换成字符流输出到控制台上
BufferedReader bw = new BufferedReader(
new InputStreamReader(is));
//输出全部信息
String str = bw.readLine();
System.out.println(str);
//关闭流
bw.close();
is.close();
pw.close();
os.close();
socket.close();
}
public static void main(String[] args) throws Exception {
new Client().start();
}
}
package com.rjxy.TCP.v1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 1.定义成员变量套接字
2.在构造方法中初始化
3.start方法处理读写
4.main方法创建对象,调用start方法
* @author 陶沅玱
*
*/
public class Server {
//1.定义套接字对象
private ServerSocket serverSocket;
public Server() {
try {
//实例化套接字对象
serverSocket = new ServerSocket(6666);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//创建strat方法处理读写
public void start() throws Exception {
//2.接受客户端的请求
System.out.println("等待客户端输入:");
Socket socket = serverSocket.accept();
System.out.println("客户端完成输入:");
//3.创建输入流,读数据
InputStream is = socket.getInputStream();
//把字节流转换成字符流读出
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
//成功读取数据
String str = br.readLine();
System.out.println(str);
//完成服务器的响应
str = "服务器:" + str;
//4.创建输出流,写操作
OutputStream os = socket.getOutputStream();
//打印流
PrintWriter pw = new PrintWriter(os);
//完成服务器的响应
pw.println(str);
pw.flush();
//5.关闭流
pw.close();
os.close();
br.close();
is.close();
socket.close();
serverSocket.close();
}
public static void main(String[] args) throws Exception {
new Server().start();
}
}
🔺v2:
package com.rjxy.TCP.v2;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client {
//1.定义套接字对象
private Socket socket;
public Client() {
try {
socket = new Socket("localhost", 6666);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
//2.创建输出流,完成对服务器的请求
OutputStream os = socket.getOutputStream();
//利用打印流输出
PrintWriter pw = new PrintWriter(os);
//从键盘获取数据
Scanner sc = new Scanner(System.in);
System.out.print("Input");
String str = sc.next();
//给服务器发出请求
pw.println(str);
pw.flush();
//3.创建输入流,接受服务器的响应,并在控制台打印输出
InputStream is = socket.getInputStream();
//把字节流转换成字符流,方便打印
BufferedReader bw = new BufferedReader(
new InputStreamReader(is));
String msg = bw.readLine();
System.out.println(msg);
//4.关闭流
bw.close();
is.close();
pw.close();
os.close();
socket.close();
}
public static void main(String[] args) throws Exception {
new Client().start();
}
}
package com.rjxy.TCP.v2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
//1.定义套接字对象
private ServerSocket serverSocket;
public Server(){
try {
//实例化套接字对象
serverSocket = new ServerSocket(6666);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
//2.建立与客户端的连接
System.out.println("等待客户端的请求:");
Socket socket = serverSocket.accept();
System.out.println("成功接受客户端的请求!");
//3.创建输入流,接受客户端的数据
InputStream is = socket.getInputStream();
//将字节流转换成字符流
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
//接收到数据
String str = br.readLine();
System.out.println(str);
//完成服务器的响应
str = "服务器: " + str;
//4.创建输出流,完成对客户端的响应
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.println(str);
pw.flush();
//5.关闭
pw.close();
os.close();
br.close();
is.close();
socket.close();
serverSocket.close();
}
public static void main(String[] args) throws Exception {
new Server().start();
}
}
🔺v3:
package com.rjxy.TCP.v3;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
*
1.一个客户端和服务器多次会话
2.客户端使用while循环输入
3.服务器端使用while循环接收数据
* @author 陶沅玱
*
*/
public class Client {
//1.定义套接字对象
private Socket socket;
public Client() {
try {
socket = new Socket("localhost", 6666);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
OutputStream os;
PrintWriter pw;
InputStream is;
BufferedReader br;
while(true) {
//2.创建输出流,完成对服务器的请求
os = socket.getOutputStream();
//利用打印流输出
pw = new PrintWriter(os);
//从键盘获取数据
Scanner sc = new Scanner(System.in);
System.out.print("Input");
String str = sc.next();
//给服务器发出请求
pw.println(str);
pw.flush();
//3.创建输入流,接受服务器的响应,并在控制台打印输出
is = socket.getInputStream();
//把字节流转换成字符流,方便打印
br = new BufferedReader(
new InputStreamReader(is));
String msg = br.readLine();
System.out.println(msg);
}
//因为设置的是死循环,所以不用关闭流
//4.关闭流
// bw.close();
// is.close();
// pw.close();
// os.close();
// socket.close();
}
public static void main(String[] args) throws Exception {
new Client().start();
}
}
package com.rjxy.TCP.v3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
1.一个客户端和服务器多次会话
2.客户端使用while循环输入
3.服务器端使用while循环接收数据
* @author 陶沅玱
*
*/
public class Server {
//1.定义套接字对象
private ServerSocket serverSocket;
public Server(){
try {
//实例化套接字对象
serverSocket = new ServerSocket(6666);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
//2.建立与客户端的连接
System.out.println("等待客户端的请求:");
Socket socket = serverSocket.accept();
System.out.println("成功接受客户端的请求!");
InputStream is;
BufferedReader br;
OutputStream os;
PrintWriter pw;
while(true) {
//3.创建输入流,接受客户端的数据
is = socket.getInputStream();
//将字节流转换成字符流
br = new BufferedReader(
new InputStreamReader(is));
//接收到数据
String str = br.readLine();
System.out.println(str);
//完成服务器的响应
str = "服务器: " + str;
//4.创建输出流,完成对客户端的响应
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.println(str);
pw.flush();
}
//5.关闭
// pw.close();
// os.close();
// br.close();
// is.close();
// socket.close();
// serverSocket.close();
}
public static void main(String[] args) throws Exception {
new Server().start();
}
}
🔺v4:
package com.rjxy.TCP.v4;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 服务器实现多线程
* @author 陶沅玱
*
*/
public class Client {
//1.定义套接字对象
private Socket socket;
public Client() {
try {
socket = new Socket("localhost", 6666);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
OutputStream os;
PrintWriter pw;
InputStream is;
BufferedReader br;
while(true) {
//2.创建输出流,完成对服务器的请求
os = socket.getOutputStream();
//利用打印流输出
pw = new PrintWriter(os);
//从键盘获取数据
Scanner sc = new Scanner(System.in);
System.out.print("Input");
String str = sc.next();
//给服务器发出请求
pw.println(str);
pw.flush();
//3.创建输入流,接受服务器的响应,并在控制台打印输出
is = socket.getInputStream();
//把字节流转换成字符流,方便打印
br = new BufferedReader(
new InputStreamReader(is));
String msg = br.readLine();
System.out.println(msg);
}
//因为设置的是死循环,所以不用关闭流
//4.关闭流
// bw.close();
// is.close();
// pw.close();
// os.close();
// socket.close();
}
public static void main(String[] args) throws Exception {
new Client().start();
}
}
package com.rjxy.TCP.v4;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器实现多线程
*
* @author 陶沅玱
*
*/
public class Server {
// 1.定义套接字对象
private ServerSocket serverSocket;
public Server() {
try {
// 实例化套接字对象
serverSocket = new ServerSocket(6666);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
while(true) {
// 2.建立与客户端的连接
System.out.println("等待客户端的请求:");
Socket socket = serverSocket.accept();
System.out.println("成功接受客户端的请求!");
// 开启多线程
new Thread(new ServerThread(socket)).start();
}
// 5.关闭
// pw.close();
// os.close();
// br.close();
// is.close();
// socket.close();
// serverSocket.close();
}
// 实现服务器的多线程,可以同时会话多个客户端
private class ServerThread implements Runnable {
Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
InputStream is;
BufferedReader br;
OutputStream os;
PrintWriter pw;
while (true) {
try {
// 3.创建输入流,接受客户端的数据
is = socket.getInputStream();
// 将字节流转换成字符流
br = new BufferedReader(new InputStreamReader(is));
// 接收到数据
String str = br.readLine();
System.out.println(str);
// 完成服务器的响应
str = "服务器: " + str;
// 4.创建输出流,完成对客户端的响应
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.println(str);
pw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws Exception {
new Server().start();
}
}
🔺v5:
package com.rjxy.TCP.v5;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 任务5-v5:实现群聊
1.服务器端
定义存放所有客户端输出流对象的数组
//存放所有的客户端的输出流对象
private PrintWriter[] allOut;
构造方法中初始化
serverSocket = new ServerSocket(8888);
//初始化
allOut = new PrintWriter[0];
在响应客户端数据时,遍历数组的输出流
2.客户端
定义线程,负责接收服务器的响应信息,实现对鞋分离
* @author 陶沅玱
*
*/
public class Client {
//1.定义套接字对象
private Socket socket;
public Client() {
try {
socket = new Socket("localhost", 6666);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
OutputStream os;
PrintWriter pw;
while(true) {
//开启多线程
new Thread(new ClientThread(socket)).start();
//2.创建输出流,完成对服务器的请求
os = socket.getOutputStream();
//利用打印流输出
pw = new PrintWriter(os);
//从键盘获取数据
Scanner sc = new Scanner(System.in);
System.out.print("Input");
String str = sc.next();
//给服务器发出请求
pw.println(str);
pw.flush();
}
//因为设置的是死循环,所以不用关闭流
//4.关闭流
// bw.close();
// is.close();
// pw.close();
// os.close();
// socket.close();
}
//定义线程,监听服务器输出的全部消息
//因此,只用把输入流放到线程即可
private class ClientThread implements Runnable{
Socket socket;
InputStream is;
BufferedReader br;
public ClientThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
//3.创建输入流,接受服务器的响应,并在控制台打印输出
is = socket.getInputStream();
//把字节流转换成字符流,方便打印
br = new BufferedReader(
new InputStreamReader(is));
String msg = br.readLine();
System.out.println(msg);
}catch(Exception e) {
}
}
}
public static void main(String[] args) throws Exception {
new Client().start();
}
}
package com.rjxy.TCP.v5;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
/**
* 任务5-v5:
* 1.实现群聊 1.服务器端 定义存放所有客户端输出流对象的数组 //存放所有的客户端的输出流对象 private PrintWriter[] allOut;
* 构造方法中初始化 serverSocket = new ServerSocket(8888);
* 初始化 allOut = new PrintWriter[0];
* 在响应客户端数据时,遍历数组的输出流
* 2.客户端 定义线程,负责接收服务器的响应信息,实现对鞋分离
*
* @author 陶沅玱
*
*/
public class Server {
// 1.定义套接字对象
private ServerSocket serverSocket;
// 定义存放所有客户端输出流对象的数组
private PrintWriter[] allOut = {};
public Server() {
try {
// 实例化套接字对象
serverSocket = new ServerSocket(6666);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
while (true) {
// 2.建立与客户端的连接
System.out.println("等待客户端的请求:");
Socket socket = serverSocket.accept();
System.out.println("成功接受客户端的请求!");
// 开启多线程
new Thread(new ServerThread(socket)).start();
}
// 5.关闭
// pw.close();
// os.close();
// br.close();
// is.close();
// socket.close();
// serverSocket.close();
}
// 实现服务器的多线程,可以同时会话多个客户端
private class ServerThread implements Runnable {
Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
InputStream is;
BufferedReader br;
OutputStream os;
PrintWriter pw;
// 3.创建输入流,接受客户端的数据
is = socket.getInputStream();
// 将字节流转换成字符流
br = new BufferedReader(new InputStreamReader(is));
// 4.创建输出流,完成对客户端的响应
os = socket.getOutputStream();
pw = new PrintWriter(os);
// 将输出流对象存放到数组中
// 先扩容
allOut = Arrays.copyOf(allOut, allOut.length + 1);
// 存放对象(即客户端)
allOut[allOut.length - 1] = pw;
while (true) {
try {
// 接收到数据
String str = br.readLine();
System.out.println(str);
// 完成服务器的响应
str = "服务器: " + str;
// allOut数组里面存放的所有输出流对象(客户端)都会收到这个消息
for (PrintWriter p : allOut) {
p.println(str);
p.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (Exception e) {
}
}
}
public static void main(String[] args) throws Exception {
new Server().start();
}
}
▲v6:
package com.rjxy.TCP.v6;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* 实现窗口化群聊
*
* @author 陶沅玱
*
*/
public class Client extends JFrame {
// 1.定义套接字对象
private Socket socket;
private PrintWriter pw = null;
public Client() {
build();
try {
socket = new Socket("localhost", 6666);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 创建窗口组件
// 创建文本区
JTextArea ta = new JTextArea();
// 创建文本框
JTextField tf = new JTextField(16);
// 创建按钮
JButton send = new JButton("发送");
// 添加组件到窗口容器
public void build() {
this.add(ta, BorderLayout.CENTER);
JPanel p = new JPanel();
p.add(tf);
p.add(send);
this.add(p, BorderLayout.SOUTH);
// 设置窗口的属性
this.setTitle("聊天室");
this.setSize(420, 300);
this.setLocationRelativeTo(null);
// 显示
this.setVisible(true);
// 完成send按钮的事件监听
send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
pw.println(tf.getText());
pw.flush();
}
});
}
public void start() {
new Thread(new ClientThread(socket)).start();
// 2.获取输出流,写信息
OutputStream out;
try {
out = socket.getOutputStream();
pw = new PrintWriter(out);
Scanner sc = new Scanner(System.in);
// while (true) {
// 从控制台输入获取信息
// System.out.println("Input:");
// String msg = sc.next();
//
// pw.println(msg);
// pw.flush();
// }
} catch (IOException e) {
e.printStackTrace();
}
// } finally {
// // 4.关闭流
// try {
//
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
}
// 定义线程,监听服务器输出的全部消息
// 因此,只用把输入流放到线程即可
private class ClientThread implements Runnable {
Socket socket;
InputStream is;
BufferedReader br;
public ClientThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 3.创建输入流,接受服务器的响应,并在控制台打印输出
is = socket.getInputStream();
// 把字节流转换成字符流,方便打印
br = new BufferedReader(new InputStreamReader(is));
String msg = br.readLine();
System.out.println(msg);
//打印到窗口中
String str = "";
while((str = br.readLine()) != null) {
//System.out.println(msg);
ta.append(str + "\n");
}
} catch (Exception e) {
}
}
}
public static void main(String[] args) throws Exception {
new Client().start();
}
}
package com.rjxy.TCP.v6;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
/**
* 实现窗口化群聊
* @author 陶沅玱
*
*/
public class Server {
// 1.定义套接字对象
private ServerSocket serverSocket;
// 定义存放所有客户端输出流对象的数组
private PrintWriter[] allOut = {};
public Server() {
try {
// 实例化套接字对象
serverSocket = new ServerSocket(6666);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start() throws Exception {
while (true) {
// 2.建立与客户端的连接
System.out.println("等待客户端的请求:");
Socket socket = serverSocket.accept();
System.out.println("成功接受客户端的请求!");
// 开启多线程
new Thread(new ServerThread(socket)).start();
}
// 5.关闭
// pw.close();
// os.close();
// br.close();
// is.close();
// socket.close();
// serverSocket.close();
}
// 实现服务器的多线程,可以同时会话多个客户端
private class ServerThread implements Runnable {
Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
InputStream is;
BufferedReader br;
OutputStream os;
PrintWriter pw;
// 3.创建输入流,接受客户端的数据
is = socket.getInputStream();
// 将字节流转换成字符流
br = new BufferedReader(new InputStreamReader(is));
// 4.创建输出流,完成对客户端的响应
os = socket.getOutputStream();
pw = new PrintWriter(os);
// 将输出流对象存放到数组中
// 先扩容
allOut = Arrays.copyOf(allOut, allOut.length + 1);
// 存放对象(即客户端)
allOut[allOut.length - 1] = pw;
while (true) {
try {
// 接收到数据
String str = br.readLine();
System.out.println(str);
// 完成服务器的响应
str = "服务器: " + str;
// allOut数组里面存放的所有输出流对象(客户端)都会收到这个消息
for (PrintWriter p : allOut) {
p.println(str);
p.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (Exception e) {
}
}
}
public static void main(String[] args) throws Exception {
new Server().start();
}
}