Java多线程聊天器
最近学习java用多线程和IO写了一个简单的聊天器。了解了UDP和TCP协议。
UDP主要就是通过DatagramSocket打包数据发送数据,不管你收没收到,我知道我发了就行。
TCP需要建立链接,你要不建立链接就不能发东西。通过ServerSocket的通道用IO发送和接受数据。
(在这就不说UDP了直接说TCP)
TCP有发送端(客户端)和接收端(服务器)
测试类:
package TCP;
public class TCPChatRoom {
public static void main(String[] args){
ServerDemoThread sdt = new ServerDemoThread(true);
ClientDemoThread cdt = new ClientDemoThread();
cdt.start();
sdt.start();
}
}
因为先运行发送端会报错,所以我给接收端传入一个flag
标记,在接收端定义一个带有boolean
形参的构造函数,如果flag
为true
则说明先启动了接收端可以继续运行,如果flag
为false
则说明先启动了发送端,必须让发送端线程等待。在发送端线程调用wait()
方法等flag
为true
时调用notify()
方法。
接收端(服务器):
package TCP;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemoThread extends Thread {
public static boolean flag=false;
public ServerDemoThread(boolean flag){
this.flag = flag;
}
@Override
public synchronized void run() {
//因为Thread类的run方法的没有跑出异常,所以在所有代码中必须将一场try catch,
但是在try中可能无法创建对象,所以要在try外边创建,避免空指针异常。
ServerSocket ss = null;
Socket s = null;
BufferedReader br = null;
try {
//指定端口
ss = new ServerSocket(22222);
//阻塞式接受
s = ss.accept();
//获取输入流
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ((line = br.readLine()) != null)
{
System.out.println(line);
}
}catch (IOException e)
{
e.printStackTrace();
}
//最终释放资源
finally {
try {
s.close();
}catch (IOException e)
{
e.printStackTrace();
}
}
}
}
发送端(客户端):
package TCP;
import java.io.*;
import java.net.Socket;
public class ClientDemoThread extends Thread {
@Override
public synchronized void run() {
if(!ServerDemoThread.flag){
try {
//如果先启动了发送线程,则flag=fales;就会进行等待
this.wait();
} catch (InterruptedException e) {e.printStackTrace(); }
}
else {
当
this.notify();
Socket s = null;
BufferedReader br = null;
BufferedWriter bw = null;
try {
//指定发送位置的IP和端口号。
s = new Socket("192.168.1.100", 22222);
//标准输入流,要发送的数据
br = new BufferedReader(new InputStreamReader(System.in));
//输出流,通过通道将数据流出
bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
String line = null;
try {
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
} catch (IOException e) {e.printStackTrace();
}
//释放资源
finally {
try {
s.close();
} catch (IOException e) {e.printStackTrace(); }
}
}
}
}