欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-11 09:46:20
...
网络通信之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();
			}
		}
	}
相关标签: socket thread