Socket初步编程——简单实现群聊
初次接触到socket网络编程,也参考了网络上众前辈的文章。尝试自己也写了一下,记录下过程吧:
服务端:(接收客户端消息并把它们打印出来)
public class SocketServer { private List<Socket> socketList = new ArrayList<Socket>(); public static void main(String[] args) { SimServer ss = new SimServer(); try { ss.service(); } catch (IOException e) { e.printStackTrace(); } } public void service() throws IOException { ServerSocket server = new ServerSocket(7001); SimServer ss = new SimServer(); while (true) { Socket socket = server.accept(); socketList.add(socket); ServerThread st = new ServerThread(socket, socketList); st.start(); } } class ServerThread extends Thread { private Socket client; private List<Socket> socketList; public ServerThread(Socket client, List<Socket> socketList) { this.client = client; this.socketList = socketList; } @Override public void run() { BufferedReader in = null; PrintWriter out = null; try { in = new BufferedReader(new InputStreamReader(client.getInputStream())); while (true) { String msg = in.readLine(); System.out.println(InetAddress.getLocalHost().getHostAddress() + " 客户端请求:" +msg); // System.out.print("服务端请输入:"); // String input = new BufferedReader(new InputStreamReader(System.in)).readLine(); System.out.println(); for(int i=0; i<socketList.size(); i++) { // out = new PrintWriter(client.getOutputStream()); out = new PrintWriter(socketList.get(i).getOutputStream()); out.println("服务端返回:" + msg); out.println(); out.flush(); // out.println("Server handle: " + Arrays.toString(msg.getBytes())); // out.write("Server handle: " + Arrays.toString(msg.getBytes())); // String lineSeprator = (String) java.security.AccessController.doPrivileged( // new sun.security.action.GetPropertyAction("line.separator")); // out.write(lineSeprator); // if (msg.equals("bye")) { // break; // } } } } catch(IOException ex) { ex.printStackTrace(); } finally { try { in.close(); } catch (Exception e) {} try { out.close(); } catch (Exception e) {} try { // client.close(); } catch (Exception e) {} } } } }
客户端:(发送消息并接收消息,这个应该是异步的,所以必须创建两个线程)
public class SocketClient { class Send extends Thread { private Socket socket; public Send(Socket socket) { this.socket = socket; } @Override public void run() { PrintWriter out = null; BufferedReader input = null; try { out = new PrintWriter(socket.getOutputStream()); input = new BufferedReader(new InputStreamReader(System.in)); while (true) { System.out.print(InetAddress.getLocalHost().getHostAddress()+" 客户端请输入:"); String msg = input.readLine(); out.println(msg); out.flush(); } // socket.close(); } catch (IOException e) { e.printStackTrace(); }finally { try { if(input != null) input.close(); if(out != null) out.close(); // if(socket != null) // socket.close(); } catch (Exception e) {} } } } class Recv extends Thread { private Socket socket; public Recv(Socket socket) { this.socket = socket; } @Override public void run() { BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); while (true) { System.out.println(); String msg = reader.readLine(); System.out.println(msg); } } catch (IOException e) { e.printStackTrace(); }finally { try { if(reader != null) reader.close(); // if(socket != null) // socket.close(); } catch (Exception e) {} } } } public static void main(String[] args) { SimClient sc = new SimClient(); try { Socket s = new Socket("localhost", 7001); sc.new Recv(s).start(); sc.new Send(s).start(); } catch (Exception e) { e.printStackTrace(); } } }
(可在另一台机器上有一个一模一样的客户端,只不过ip地址要改为服务器所在的机器的ip)
-----------------------------------
在此过程中,发现了几点:
1)服务端用的是ServerSocket,每当有一个客户端连接上服务端,就会触发serverSocket.accept()产生一个socket用于和客户端交互;
2)PrintWriter.write(String msg)无法把消息发出去,而PrintWriter.println(String msg)则可以,但println(String msg)相当于(要同时write lineSeprator):
out.write("Server handle: " + Arrays.toString(msg.getBytes()));
String lineSeprator = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
out.write(lineSeprator);
3)服务端线程必须把socketList传进来,它才能知道有几个客户端连着它。
上一篇: nodejs实现web服务实例
下一篇: Haproxy搭建Web群集实操