网络编程,集合,IO,多线程,内部类的综合应用

应用案例

多人在线双人石头剪刀布游戏

如下图:

当有两或两以上客户端连接服务端时,其中两两客户之间可进行石头剪刀布游戏,服务端记录哪两个客户在进行游戏

服务端代码如下:

package com.qianfeng.cl;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 
 * @Title BookServer.java
 * @Package com.qianfeng.cl
 * @Description book服务端
 * @author CL 
 * @date 2020年3月29日
 * @version 1.0
 */
public class BookServer {

	public static void main(String[] args) {
		
		//服务端
		ServerSocket server = null;
		
		//接收Socket
		Socket socket = null;
		
		//使用队列存储Socket
		Queue<Socket> list = new LinkedList<Socket>();
		
		//固定线程的线程池,不进行关闭
		ExecutorService  service = Executors.newScheduledThreadPool(5);
		
		try {
			
			//启动一个端口为6666的客户端
			server = new ServerSocket(6666);
			
			//循环接收Socket
			while(true) {
				
				//开启监听获取Socket
				socket = server.accept();
				
				//添加到队列
				list.offer(socket);
				
				if(list.size() > 1) {
					
					Socket skt1 = list.poll();
					Socket skt2 = list.poll();
					//添加到线程池
					service.execute(new MyRunnable(skt1,skt2));
					//控制台打印那两人进行游戏
					System.out.println(skt1.getLocalAddress()+" and "+skt2.getLocalAddress());
					
				}	
			}		
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
//发送和接收消息
class MyRunnable implements Runnable{

	private Socket socket1;
	
	private Socket socket2;
	
	public MyRunnable(Socket socket1,Socket socket2) {
		this.socket1 = socket1;
		this.socket2 = socket2;
	}
	
	
	@Override
	public void run() {
		
		//定义固定线程数的线程池
		ExecutorService  executorService = Executors.newScheduledThreadPool(2);
		
		//添加一个线程
		Future<String> future1 = executorService.submit(new MyCallable(this.socket1));
		
		//添加一个线程
		Future<String> future2 = executorService.submit(new MyCallable(this.socket2));
		
		String str1;
		
		String str2;
		
		try {
			//接收socket1发送回的消息
			str1 = future1.get();
			
			//接收socket2发送回的消息
			str2 = future2.get();
			
			String s1 = "my:"+str1+"\tta"+str2;
			String s2 = "my:"+str2+"\tta"+str1;
			
			executorService.submit(new Reply(this.socket1,s1));
			executorService.submit(new Reply(this.socket2,s2));
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}finally {
			executorService.shutdown();
		}
	}
	//发送消息并接收返回的消息
	class MyCallable implements Callable<String>{

		private Socket socket;
		
		public MyCallable(Socket socket) {
			this.socket = socket;
		}
		
		
		@Override
		public String call() throws Exception {
			
			String str = "1:石头\t2:剪刀\t3:布\t=======请输入:";
			
			//获取输出流
			OutputStream outputStream= socket.getOutputStream();
		
			PrintWriter  output = new PrintWriter(outputStream);
			
			//发送消息
			output.println(str);
			
			output.flush();
			
			//获取输入流
			InputStream inputStream= socket.getInputStream();
			
			@SuppressWarnings("resource")
			Scanner input = new Scanner(inputStream);
			
			//接收消息
			str = input.nextLine();

			return str;
		}
		
	}
	//发送结果
	class Reply implements Runnable{

		private Socket socket;
		
		private String str;
		
		public Reply(Socket socket,String str) {
			this.socket = socket;
			this.str = str;
		}
		
		@Override
		public void run() {
			
			OutputStream output;
			
			PrintWriter prt;
			try {
				//获取输出流
				output = socket.getOutputStream();
				
				prt = new PrintWriter(output);
				
				//发送结果
				prt.println(this.str);
				
				prt.close();
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

客户端代码如下:

package com.qianfeng.cl;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
 * 
 * @Title BookClient.java
 * @Package com.qianfeng.cl
 * @Description 客户端代码
 * @author CL 
 * @date 2020年3月29日
 * @version 1.0
 */
public class BookClient {

	static boolean bl1 = true;
	static boolean bl2 = true;

	@SuppressWarnings("resource")
	public static void main(String[] args) {

		try {
		    //与服务端建立连接
			Socket s = new Socket("127.0.0.1", 6666);

			System.out.println(s.getInetAddress() + " online...");

			new Thread(new Runnable() {

				@Override
				public void run() {

					System.out.print("please wait connection ");
					while (bl1) {

						System.out.print(".");
						try {
							Thread.sleep(999);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}).start();
            //获取服务端发送的信息
			Scanner sc = new Scanner(s.getInputStream());
			String res = sc.nextLine();
			
			bl1 = false;
			
			try {
				Thread.sleep(123);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			
			System.out.println("");
			//打印服务端发送的信息
			System.out.println(res);

			Scanner n = new Scanner(System.in);
			String a = n.nextLine();
            
            
			PrintWriter pw = new PrintWriter(s.getOutputStream());
			//给服务端发送信息
			pw.println(a);
			pw.flush();

			new Thread(new Runnable() {

				@Override
				public void run() {

					System.out.print("please wait your opponent input ");
					while (bl2) {

						System.out.print(".");
						try {
							Thread.sleep(888);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}).start();
            //接收服务端发送过来的信息
			res = sc.nextLine();

			bl2 = false;

			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			System.out.println("");
			//打印服务端发来的信息
			System.out.println(res);

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值