网络通信之server/client通信的实现

网络通信之server/client通信的实现

要求:实现服务器客户端通信,当服务器启动后一旦有客户端连接上服务器,服务器便给连接上的客户端发送”欢迎光临!“。每增加一个客户端,服务器都将客户端放入arraylist中,并显示在线客户端数。而客户端向服务器发送消息时,服务器会接收客户端发来的消息并将消息转发给所以在线的客户端。客户端和服务器端都有自己的发送和接收数据的线程。
服务端要求实现的功能:
      1.每连上一个客户端,就主动给客户端发送一句“欢迎光临!”。
      2.使用ArrayList存放连上服务端的所有客户端。
      3.当接收到客户端发送来的消息的时候,将这条消息转发给所有连上服务端的所有客户端。

思路:
      1.创建一个服务器套接字(ServerSocket),绑定到指定端口。
     2.调用accept方法,侦听来自客户端的请求,如果客户发出请求,则接受连接,返回通信套接字(Socket)。
      3.创建线程来处理客户机:发送和接收消息。


服务端:
//服务器端
public class MyServer {
	//使用ArrayList存放连上服务端的所有客户端
	public static ArrayList<Socket> sockets = new ArrayList<Socket>();
	public static void main(String[] args) {
			try {
				//创建一个服务器套接字,绑定到54321端口
				ServerSocket server = new ServerSocket(54321);
				System.out.println("服务器已启动,正在等待连接");
				while (true) {
					//调用accept方法,侦听来自客户端的请求
					Socket socket = server.accept();
					//将客户端发送过来的通信套接字添加到sockets动态数组中
					sockets.add(socket);
					//输出在线的客户端个数
					System.out.println("有" + sockets.size() + "个客户连接上");
					//启动发送线程,给客户端发送一句“欢迎光临!”
					new getOutputStream(socket).start();
					//启动接收线程,读取从客户端发来的消息
					new getInputStream(socket).start();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


服务端负责发送欢迎光临的线程类:
//发送线程负责给客户端发送一句“欢迎光临!”
	class getOutputStream extends Thread{
		private Socket s;
		public getOutputStream(Socket s) {
			this.s=s;
		}
		@Override
		public void run() {
			try {
				//获取输出流
				OutputStream ops= s.getOutputStream();
				String msg="欢迎光临!\n";
				//将msg写入流
				ops.write(msg.getBytes());
				//刷新流
				ops.flush();
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


服务器端从客户端接收数据的线程类:
//接收线程,读取从客户端发来的消息
	class getInputStream extends Thread {
		private Socket r;
		public getInputStream(Socket r) {
			this.r = r;
		}
		public void run() {
			try {
				//获取输入流
				InputStreamReader is = new InputStreamReader(r.getInputStream());
				BufferedReader br = new BufferedReader(is);
				while (true) {
					//读取客户端发送过来的消息
					String msg = br.readLine();
					System.out.println("客户端发来" + msg);
					//读取客户端发送过来的消息后转发给所有在线的客户端
					for (Socket socket : MyServer.sockets) {
						OutputStreamWriter osw = new OutputStreamWriter(
								socket.getOutputStream());
						BufferedWriter bw = new BufferedWriter(osw);
						bw.write(msg + "\n");
						//刷新流
						bw.flush();
						
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}



客户端
功能:
      1.在命令行给服务端发送消息
      2.当接收到服务端发来的消息的时候,将内容显示在控制台上
思路:
      1.创建一个套接字(Socket) ,向服务器的侦听端口发出请求
      2.与服务器正确连接后,获得输入/输出流,启动线程开始网络数据的接收和发送


客户端:
//客户端
public class MyClient {
		public static void main(String[] args) {
			try {
				//创建一个套接字(Socket) ,向服务器的侦听端口发出请求
				Socket socket = new Socket("localhost", 54321);
				//启动读取数据线程,接收服务器发送过来的消息
				new Cread(socket).start();
				//启动发送数据线程,给服务器发送消息
				new Csend(socket).start();
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


客户端接收数据的线程类:
//读取数据线程,接收服务器发送过来的消息
	class Cread extends Thread {
		private Socket r;
		public Cread(Socket r) {
			this.r = r;
		}
		public void run() {
			try {
				while (true) {
					//获取输入流
					InputStreamReader is = new InputStreamReader(r.getInputStream());
					BufferedReader br = new BufferedReader(is);
					//按行读取从服务器发来的数据消息
					String content = br.readLine();
					System.out.println("服务端发来" + content);
				}
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


客户端发送数据线程类:
//发送数据线程,给服务器发送消息
	class Csend extends Thread {
		private Socket c;
		public Csend(Socket c) {
			this.c = c;
		}
		public void run() {
			try {
				//获取输出流
				OutputStreamWriter osw = new OutputStreamWriter(c.getOutputStream());
				BufferedWriter bw = new BufferedWriter(osw);
				//从键盘写入数据
				Scanner sc = new Scanner(System.in);
				while (true) {
					//将键盘写入的数据按行写入发送给服务器
					String msg = sc.nextLine() + "\n";
					bw.write(msg);
					System.out.println("给服务器发送" + msg);
					//刷新流
					bw.flush();
				}
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

猜你喜欢

转载自sunflower-13.iteye.com/blog/2334767