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传进来,它才能知道有几个客户端连着它。

猜你喜欢

转载自raising.iteye.com/blog/2221919