- 实现方案
- 基本说明
- user1
- user2
- 代码实现
- 测试
- 拓展——增加user3
- 测试
TCP + 多线程
基本说明 user1user1 实际上是作为服务器端,在本机暴露9999端口,使用accept()函数实现监听,需要先开始user1的程序,再开启user2程序。
user1有类 user1_send 和 user1_listen 分别负责发送和监听。
user2user2 实际上是作为客户端,使用Socket(“127.0.0.1”,9999)设置目标地址和端口,发送连接请求。
user2有类 user2_send 和 user2_listen 分别负责发送和监听。
代码实现user1.java
public class user1 { public static void main(String[] args) throws IOException { System.out.println("======用户1已上线======="); ServerSocket serverSocket = new ServerSocket(9999); //当没有接受到套接字请求时,程序阻塞在accept()函数处, //一旦接收到套接字请求,则开启相应的监听和发送线程,并且进行下一个循环,建立新的套接字 while (true){ //不断接收客户请求,为每一个客户创建一个独立的线程去处理每个客户的请求 Socket socket = serverSocket.accept(); new Thread(new user1_listen(socket)).start(); new Thread(new user1_send(socket)).start(); } } } //用来监听user2的请求 class user1_listen implements Runnable{ private Socket socket; public user1_listen(Socket socket) { this.socket = socket; } public void run() { try { ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); while (true){ System.out.println(ois.readObject()); } } catch (Exception e) { e.printStackTrace(); } finally { //当客户断开连接或出现异常,服务器的socket需要断开,没有必要保持连接而浪费资源 try { socket.close(); } catch (Exception e) { e.printStackTrace(); } } } } //用来发送消息 class user1_send implements Runnable{ private Socket socket; public user1_send(Socket socket) { this.socket = socket; } public void run() { try { ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); Scanner scanner = new Scanner(System.in); while(true){ //读取键盘输入 String string = scanner.nextLine(); //将内容写入通信管道 oos.writeObject("user1发送:"+string); oos.flush(); } } catch (IOException e) { e.printStackTrace(); } } }
user2.java
package com.bhy.qq; import org.json.simple.JSONObject; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.Scanner; public class user2 { private static Socket socket; private static boolean connection_state = false; public static void main(String[] args) { connect(); System.out.println("======用户2已上线======="); if(connection_state){ new Thread(new user2_listen(socket)).start(); new Thread(new use2_send(socket)).start(); } } //连接user1 public static void connect(){ try { socket = new Socket("127.0.0.1",9999); connection_state = true; } catch (IOException e) { e.printStackTrace(); connection_state=false; } } } //用来接收user1传来的信息 class user2_listen implements Runnable{ private Socket socket; public user2_listen(Socket socket) { this.socket = socket; } public void run() { try { ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); while (true){ System.out.println(ois.readObject()); } } catch (Exception e) { e.printStackTrace(); } } } //用来发送消息 class use2_send implements Runnable{ private Socket socket; public use2_send(Socket socket) { this.socket = socket; } public void run() { try { ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); Scanner scanner = new Scanner(System.in); while(true){ //读取输入 String string = scanner.nextLine(); oos.writeObject("user2发送:"+string); oos.flush(); } } catch (Exception e) { e.printStackTrace(); } } }测试
先开启user1,再开启user2。
user1先发送 hello,user2 , I ’ m user1!!
user2发送 hello , I ’ m user 2! ^*^
user1窗口
user2窗口
此外,可以无限增加用户与user1通信,因为user1是服务端,并且不断有新的套接字监听,可以建立多个套接字连接。
关键代码如下
user1.java
//当没有接受到套接字请求时,程序阻塞在accept()函数处, //一旦接收到套接字请求,则开启相应的监听和发送线程,并且进行下一个循环,建立新的套接字 while (true){ //不断接收客户请求,为每一个客户创建一个独立的线程去处理每个客户的请求 Socket socket = serverSocket.accept(); new Thread(new user1_listen(socket)).start(); new Thread(new user1_send(socket)).start(); }测试
user3.java
和user2代码几乎一样,把代码中的 2 改成 3 即可
public class user3{ private static Socket socket; private static boolean connection_state = false; public static void main(String[] args) { connect(); System.out.println("======用户3已上线======="); if(connection_state){ new Thread(new user3_listen(socket)).start(); new Thread(new use3_send(socket)).start(); } } //连接user1 public static void connect(){ try { socket = new Socket("127.0.0.1",9999); connection_state = true; } catch (IOException e) { e.printStackTrace(); connection_state=false; } } } class user3_listen implements Runnable{ private Socket socket; public user3_listen(Socket socket) { this.socket = socket; } public void run() { try { ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); while (true){ System.out.println(ois.readObject()); } } catch (Exception e) { e.printStackTrace(); } } } class use3_send implements Runnable{ private Socket socket; public use3_send(Socket socket) { this.socket = socket; } public void run() { try { ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); Scanner scanner = new Scanner(System.in); while(true){ String string = scanner.nextLine(); oos.writeObject("user3发送:"+string); oos.flush(); } } catch (Exception e) { e.printStackTrace(); } } }
结果:
user3输入3testing
user2输入 2testing
但是新的问题会出现,user1发送的消息会随机发送给user2或user3,因为此时user1同时有两个发送线程,不知道发送的时候会用到哪一个。在这里不给出解决方案(主要不会/(ㄒoㄒ)/~~
所以user1只能实现接收多方信息的功能,不能精准发送消息
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)