开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情
1.信息发送的分配(运用到多线程)
在这里进行多线程的顺序,先获取用户名字如果跟正在使用的人的名字那就放在yourmessages函数里,反之放到其他人的函数里
if (msg.getName().equals(usernameLabel.getText())) {
Thread t2 = new Thread(yourMessages);
t2.setDaemon(true);
t2.start();
} else {
Thread t = new Thread(othersMessages);
t.setDaemon(true);
t.start();
}
一.socket网络编程 1.在C/S软件架构程序设计技术中,实现网络通信的两个应用进程,一个叫做服务进程,另一个叫做客户进程。
java的TCP/IP套接字编程则将底层的细节进行了封装:
两个套接字类: ServerSocket:服务进程中 Socket:客户进程
服务进程首先开启一个或多个监听端口,客户进程向服务进程发起TCP三次握手连接。TCP连接成功后,逻辑上可理解为通信进程的双方具有两个流(输出流和输入流)。逻辑上可将两个流理解为两个通信管道的全双工通信模式,一个用于向对方发送数据,另一个用于接收对方的数据。
通信管道的入口:
- socket.getInputStream() 方法可获得输入字节流的入口地址;
- socket.getOutputStream() 方法可获得输出字节流的出口地址;
2.释放过程
3.TCPServer的源代码
public class TCPServer {
private int port = 8008; // 服务器监听端口
private ServerSocket serverSocket; // 定义服务器套接字
public TCPServer() throws IOException {
serverSocket = new ServerSocket(port);
System.out.println("服务器启动监听在 " + port + " 端口");
}
private PrintWriter getWriter(Socket socket) throws IOException {
// 获得输出流缓冲区的地址
OutputStream socketOut = socket.getOutputStream();
// 网络流写出需要使用 flush ,这里在 PrintWriter 构造方法中直接设置为自动 flush
return new PrintWriter(
new OutputStreamWriter(socketOut, "utf-8"), true);
}
private BufferedReader getReader(Socket socket) throws IOException {
// 获得输入流缓冲区的地址
InputStream socketIn = socket.getInputStream();
return new BufferedReader(
new InputStreamReader(socketIn, "utf-8"));
}
// 单客户版本,即每一次只能与一个客户建立通信连接
public void Service() {
while (true) {
Socket socket = null;
try {
// 此处程序阻塞等待,监听并等待客户发起连接,有连接请求就生成一个套接字。
socket = serverSocket.accept();
// 本地服务器控制台显示客户端连接的用户信息
System.out.println("New connection accepted: " + socket.getInetAddress().getHostAddress());
BufferedReader br = getReader(socket); // 定义字符串输入流
PrintWriter pw = getWriter(socket); // 定义字符串输出流
// 客户端正常连接成功,则发送服务器的欢迎信息,然后等待客户发送信息
pw.println("From 服务器:欢迎使用本服务!");
String msg = null;
// 此处程序阻塞,每次从输入流中读入一行字符串
while ((msg = br.readLine()) != null) {
// 如果客户发送的消息为 "bye" ,就结束通信
if (msg.trim().equals("bye")) {
// 向输出流中输出一行字符串 , 远程客户端可以读取该字符串
pw.println("From服务器:服务器断开连接,结束服务!");
System.out.println("客户端离开");
break; // 结束循环
}
// 向输出流中输出一行字符串 , 远程客户端可以读取该字符串
pw.println("From服务器:" + msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(socket != null)
socket.close(); // 关闭 socket 连接及相关的输入输出流
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws IOException{
new TCPServer().Service();
}
}