JAVA SOCKET编程 敏捷开发计划游戏工具(仿多人聊天室)


前言

面试的时候面试一个比较印象深刻的问题就是,有没有接触过SOCKET编程.虽然知道往后的linux课程中应该会接触到,但是等不及了,先自行操刀了.

一、敏捷开发计划游戏

在这里插入图片描述

二、代码

服务器端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import static java.lang.Thread.sleep;

public class Server extends ServerSocket {
    
    
    final static int SOCKET_PORT = 9999;
    List<Message> messages = new LinkedList<>();
    List<ClientThread> clientThreads = new ArrayList<>();

    public static void main(String[] args) throws IOException {
    
    
        new Server();
    }
    public Server() throws IOException {
    
    
        super(SOCKET_PORT);
        //创建一个线程,当消息队列满6个,即六个人都发了计划点数后,向每个socket线程发送6个人的点数
        new Thread(() -> {
    
    
            while (true) {
    
    
                int size = messages.size();
                if (size > 5) {
    
    
                    for (Message message : messages)
                        for (ClientThread clientThread : clientThreads) {
    
    
                            clientThread.sendMessage(message);
                        }
                    messages.clear();
                }
                else {
    
    
                    try {
    
    
                        //没到六个人发送时,释放cpu资源
                        sleep(500);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        while (true) {
    
    
            Socket client = accept();
            clientThreads.add(new ClientThread(client));
        }
    }


    class ClientThread extends Thread {
    
    
        BufferedReader in;
        PrintWriter out;
        String username;

        public ClientThread(Socket client) throws IOException {
    
    
            out = new PrintWriter(client.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(client.getInputStream()));
            out.println("已连接服务器,请输入您的姓名:");
            username = in.readLine();
            out.println(username+"你好!");
            System.out.println(username+"已经连接");
            start();
        }

        @Override
        public void run() {
    
    
            String line;
            try {
    
    
                while (true) {
    
    
                    //接收信息,并添加到消息链表中
                    line = in.readLine();
                    if (line != null) {
    
    
                        messages.add(new Message(username, line));
                    }
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }

        public void sendMessage(Message message) {
    
    
            out.println(message);
        }
    }
}
//消息类
class Message {
    
    
    String name;
    String msg;

    public Message(String name, String msg) {
    
    
        this.name = name;
        this.msg = msg;
    }

    @Override
    public String toString() {
    
    
        return name + ":" + msg;
    }
}

客户端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class ClientSocket extends Socket {
    
    
    static final int SERVER_PORT = 9999;
    static final String SERVER_IP = "127.0.0.1";

    public static void main(String[] args) throws IOException {
    
    
        new ClientSocket();
    }
    public ClientSocket() throws IOException {
    
    
        super(SERVER_IP, SERVER_PORT);
        PrintWriter out = new PrintWriter(getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream()));
        Scanner sc = new Scanner(System.in);
        new Thread(() -> {
    
    
            try {
    
    
                while (true) {
    
    
                    String line = in.readLine();
                    System.out.println(line);
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }).start();
        while (true) {
    
    
            String line = sc.nextLine();
            out.println(line);
        }
    }

}

三、总结

涉及到的知识:

  1. IO流 字节流、字符流 控制流 打印流
  2. Socket编程反而挺简单的,设置好端口进行连接即可
  3. 多线程

四、缺陷

  1. 线程不安全问题没有仔细解决
  2. 流没有关闭
  3. 没有设置正常退出

五、大坑

有个坑想不通.在服务器端发消息的线程中.如果我把else部分注释到,程序就没法运行了.当消息超过六条也不会发送消息.
更神奇的是,如果我debug模式下,超过六条后服务器端还是不会有反应.但是我把断点打到线程内后,程序就立刻执行到断点处.点击继续运行,程序正常向客户端发送消息.
猜测:单纯线程会抢占不到CPU资源?怪怪的,待解答

new Thread(() -> {
    
    
            while (true) {
    
    
                int size = messages.size();
                if (size > 5) {
    
    
                    for (Message message : messages)
                        for (ClientThread clientThread : clientThreads) {
    
    
                            clientThread.sendMessage(message);
                        }
                    messages.clear();
                }
             	/*
                else {
                    try {
                        //没到六个人发送时,释放cpu资源
                        sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                */
            }
        }).start();

猜你喜欢

转载自blog.csdn.net/rglkt/article/details/116025160