想用JAVA做一个服务器,请问怎么利用TCP和线程,实现多个客户端同时在线,能与服务器进行交互?
服务器监听端口 做个无限循环 接到一个连接就创建一个通道线程,并将通道线程存储到一个list集合中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; /* * 4.用socket通讯写出多个客户端和一个服务器端的通讯, * 要求客户发送数据后能够回显相同的数据(回显功能)(实用TCP方式)。 */ public class Test4Server { // 主入口 public static void main(String[] args) throws IOException { scoketServer(); } // 开启的tcp8888监听端口 public static void scoketServer() throws IOException { ServerSocket server = new ServerSocket( 8888 ); while ( true ) { // 未连通前线程阻塞,连通后开启一个socket通道线程后继续监听8888端口 Socket socket = server.accept(); System.out.println(socket.getInetAddress().getHostAddress() + "连接进入" ); new SocketThread(socket).start(); } } } // 一个服务器端口中监听多个客服端通道线程 class SocketThread extends Thread { // 所有通道写入流的集合 private static List<PrintWriter> list = new ArrayList<PrintWriter>(); private BufferedReader bufferedReader; private PrintWriter printWriter; public SocketThread(Socket socket) throws IOException { this .bufferedReader = new BufferedReader( new InputStreamReader(socket .getInputStream())); this .printWriter = new PrintWriter(socket.getOutputStream()); list.add(printWriter); } @Override public void run() { String string = null ; while ( true ) { try { // 服务器在通道中读到的信息回显给客服端 string = bufferedReader.readLine(); System.out.println( "客服端信息:" + string); for (PrintWriter printWriter:list ){ printWriter.write( "服务器回显:" + string + "\r\n" ); printWriter.flush(); } } catch (IOException e) { } } } } |
客服端代码 可以用在局域网中用多台来连接测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; public class Test4Client { public static Object obj = new Object(); // 客服端的主入口 public static void main(String[] args) throws IOException { socketClient(); } // 与服务器连通地址本机(127.0.0.1),局域网中其他机器是(服务器在局域网中的ip地址) 端口都是8888 public static void socketClient() throws IOException { Socket socket = new Socket( "127.0.0.1" , 8888 ); if (socket.isConnected()) { // 如果连接成功了就开启写和读的进程 new writer(socket).start(); new read(socket).start(); } else { System.out.println( "服务器未开启" ); } } } // 写入到通道的线程 class writer extends Thread { @SuppressWarnings ( "unused" ) private Socket socket; private PrintWriter printWriter; private Scanner scanner = new Scanner(System.in); private String str = null ; public writer(Socket socket) throws IOException { this .socket = socket; this .printWriter = new PrintWriter(socket.getOutputStream()); } @Override public void run() { scanner.useDelimiter( "\r\n" ); while ( true ) { System.out.print( "请输入信息:" ); // 产生扫描器的线程阻塞 str = scanner.next(); System.out.println( "我说:" +str); printWriter.write(str + "\r\n" ); printWriter.flush(); try { Thread.sleep( 200 ); } catch (InterruptedException e) { e.printStackTrace(); } } } } // 从通道中读取的线程 class read extends Thread { private Socket socket; private BufferedReader bufferedReader; private String str = null ; public read(Socket socket) throws IOException { this .socket = socket; this .bufferedReader = new BufferedReader( new InputStreamReader(socket .getInputStream())); } @Override public void run() { while ( true ) { try { str = bufferedReader.readLine(); System.out.println(str); } catch (IOException e) { } try { Thread.sleep( 200 ); } catch (InterruptedException e) { e.printStackTrace(); } } } } |
追问:
我是想在一个JFrame界面弄2个按钮,“启动服务器”“关闭服务器”
启动服务器之后,我做了一个这样的界面,希望能在左边的用户信息里显示连接到服务器的用户,右边的editorPane里显示IP,用户名,密码。
你给的代码可以运行但是没有在界面里面,能不能再详细介绍一下。。想了一下午都不知道怎么把那些东西加到这个界面里面去。。。TUT
追答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | public class Test4Server { // 主入口 public static void main(String[] args) throws IOException { scoketServer(); } // 开启的tcp8888监听端口 public static void scoketServer() throws IOException { ServerSocket server = new ServerSocket( 8888 ); //这里开启你的服务端界面 while ( true ) { // 未连通前线程阻塞,连通后开启一个socket通道线程后继续监听8888端口 Socket socket = server.accept(); // 这里将连接进来的 ip地址 显示在你的 服务端界面列表中: socket.getInetAddress().getHostAddress() System.out.println(socket.getInetAddress().getHostAddress() + "连接进入" ); new SocketThread(socket).start(); } } } |