TcpChat
刚学完Tcp,可以实现两个类之间相互发送信息
一个类创建ServerSocket服务 另一个类去连接
当检测到输入bye时 关闭连接 结束程序
想自我扩展一下,通过一个ServerSocket服务,让两个Socket去连接ServerSocket实现他俩之间相互发信息。
经过一顿埋头苦干
package TcpChat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
//发送线程
public class SendThread implements Runnable{
private Socket socket;
private OutputStream os;
private String msg;
byte[] bytes;
BufferedReader reader;
//构造函数中传入Socket值并初始化OutputStream、BufferedReader
public SendThread(Socket socket) throws IOException {
this.socket = socket;
os = socket.getOutputStream();
reader = new BufferedReader(new InputStreamReader(System.in));
}
@Override
public void run() {
while (!socket.isClosed()){
try {
//从键盘获得消息
msg = reader.readLine();
bytes = msg.getBytes(StandardCharsets.UTF_8);
//发送消息
os.write(bytes,0,bytes.length);
//输入“bye”时,结束接听
if (msg.equals("bye")){
System.out.println("请求关闭连接");
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
try {//关闭资源
reader.close();
//os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package TcpChat;
import java.io.*;
import java.net.Socket;
//接收线程
public class GetThread implements Runnable{
private Socket socket;
private InputStream is;
byte[] bytes;
int len;
String msg;
//构造函数中初始化socket和InputStream
public GetThread(Socket socket) throws IOException {
this.socket = socket;
is = socket.getInputStream();
bytes = new byte[1024];
}
@Override
public void run() {
while (!socket.isClosed()){
try {
//接收信息并显示
len = is.read(bytes);
msg = new String(bytes,0,len);
System.out.println(socket.getInetAddress()+":"+msg);
if (msg.trim().equals("bye")){
System.out.println("对方请求关闭连接");
socket.close();
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
/*try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}*/
}
}
package TcpChat;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
//服务器线程:负责信息的转发
public class ServerThread implements Runnable{
private int len;
private String name;
InputStream is;
OutputStream os;
byte[] buffer;
public ServerThread(Socket one,Socket two, String name) throws IOException {
this.name=name;
this.is = one.getInputStream();
this.os = two.getOutputStream();
buffer = new byte[1024];
}
@Override
public void run() {
try {
while (true){
//转发信息
len=is.read(buffer);
os.write(buffer,0,len);
System.out.println(name+"发送了信息");
//结束判断
if (new String(buffer,0,len).equals("bye")) {
System.out.println(name+"请求结束");
is.close();
os.close();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
// try {
// is.close();
// os.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
package TcpChat;
import java.io.IOException;
import java.net.Socket;
public class hong {//小红
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = new Socket("127.0.0.1",9000);
Thread thread1 = new Thread(new SendThread(socket));
Thread thread2 = new Thread(new GetThread(socket));
thread1.start();
thread2.start();
while (true){
if (!thread1.isAlive()||!thread2.isAlive()){
if (thread1.isAlive())thread1.stop();
if (thread2.isAlive())thread2.stop();
socket.close();
System.out.println("已断开连接");
break;
}
}
}
}
package TcpChat;
import java.io.IOException;
import java.net.Socket;
public class ming {//小明
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = new Socket("127.0.0.1",9000);
Thread thread1 = new Thread(new SendThread(socket));
Thread thread2 = new Thread(new GetThread(socket));
thread1.start();
thread2.start();
while (true){
if (!thread1.isAlive()||!thread2.isAlive()){
if (thread1.isAlive())thread1.stop();
if (thread2.isAlive())thread2.stop();
socket.close();
System.out.println("已断开连接");
break;
}
}
}
}
package TcpChat;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {//主服务器
public static void main(String[] args) throws IOException, InterruptedException {
//开端口
ServerSocket serverSocket = new ServerSocket(9000);
System.out.println("服务器已打开等待连接-------");
Socket socket1 = serverSocket.accept();
System.out.println("socket1已连接");
Socket socket2 = serverSocket.accept();
System.out.println("socket2已连接");
//开线程
Thread t1=new Thread(new ServerThread(socket1,socket2,"socket1"));
Thread t2=new Thread(new ServerThread(socket2,socket1,"socket2"));
t1.start();
t2.start();
//结束判断
while (true){
if (socket1.isClosed()&&socket2.isClosed()){
if (t1.isAlive())t1.stop();
if (t2.isAlive())t2.stop();
System.out.println("全部断开连接了");
break;
}
}
}
}
从一开始不断地报socket断开错误
发现好像关闭socket.getInputStream也会关闭socket
于是先删掉InputStream的关闭资源操作
但是还用了官方不推荐用的线程关闭 Thread.stop()
而且Server线程会报这个错误
再次整改
package TcpChat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
//发送线程
public class SendThread implements Runnable{
private Socket socket;
private OutputStream os;
private String msg;
byte[] bytes;
BufferedReader reader;
//构造函数中传入Socket值并初始化OutputStream、BufferedReader
public SendThread(Socket socket) throws IOException {
this.socket = socket;
os = socket.getOutputStream();
reader = new BufferedReader(new InputStreamReader(System.in));
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()){
try {
//从键盘获得消息
msg = reader.readLine();
bytes = msg.getBytes(StandardCharsets.UTF_8);
//发送消息
os.write(bytes,0,bytes.length);
//输入“bye”时,结束连接
if (msg.equals("bye")){
System.out.println("请求关闭连接");
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
try {//关闭资源
reader.close();
//os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package TcpChat;
import java.io.*;
import java.net.Socket;
//接收线程
public class GetThread implements Runnable{
private Socket socket;
private InputStream is;
byte[] bytes;
int len;
String msg;
//构造函数中初始化socket和InputStream
public GetThread(Socket socket) throws IOException {
this.socket = socket;
is = socket.getInputStream();
bytes = new byte[1024];
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()){
try {
//接收信息并显示
len = is.read(bytes);
if (len==-1)break;
msg = new String(bytes,0,len);
System.out.println(socket.getInetAddress()+":"+msg);
if (msg.trim().equals("bye")){
System.out.println("对方请求关闭连接");
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
// try {
// is.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
package TcpChat;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
//服务器线程:负责信息的转发
public class ServerThread implements Runnable{
private int len;
private String name;
InputStream is;
OutputStream os;
byte[] buffer;
String msg;
public ServerThread(Socket one,Socket two, String name) throws IOException {
this.name=name;
this.is = one.getInputStream();
this.os = two.getOutputStream();
buffer = new byte[1024];
msg = null;
}
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()){
//转发信息
len=is.read(buffer);
if (len==-1)break;
msg=new String(buffer,0,len);
System.out.println("接收到信息:"+msg);
if (msg.equals("bye")) {
os.write(buffer,0,len);
System.out.println(name+"请求结束");
break;
}
else {
os.write(buffer,0,len);
System.out.println(name+"发送了信息:"+msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
// finally {
// try {
// //is.close();
// //os.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
}
}
package TcpChat;
import java.io.IOException;
import java.net.Socket;
public class hong {//小红
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = new Socket("127.0.0.1",9000);
Thread thread1 = new Thread(new SendThread(socket));
Thread thread2 = new Thread(new GetThread(socket));
thread1.start();
thread2.start();
while (true){
if (!thread1.isAlive()&&!thread2.isAlive()){
// if (thread1.isAlive())thread1.interrupt();
// if (thread2.isAlive())thread2.interrupt();
socket.close();
System.out.println("已断开连接");
break;
}
}
}
}
package TcpChat;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {//主服务器
public static void main(String[] args) throws IOException, InterruptedException {
//开端口
ServerSocket serverSocket = new ServerSocket(9000);
System.out.println("服务器已打开等待连接-------");
Socket socket1 = serverSocket.accept();
System.out.println("socket1已连接");
Socket socket2 = serverSocket.accept();
System.out.println("socket2已连接");
//开线程
Thread t1=new Thread(new ServerThread(socket1,socket2,"socket1"));
Thread t2=new Thread(new ServerThread(socket2,socket1,"socket2"));
t1.start();
t2.start();
//结束判断
while (true){
if (!t2.isAlive()&&!t1.isAlive()){
socket1.close();
socket2.close();
System.out.println("全部断开连接了");
break;
}
}
}
}
漏洞
虽然看上去什么错都没有报
但是里面的 InputStream、OutputStream流都没有关闭资源
希望得到大佬指点