coco__007 2017-11-26 13:16 采纳率: 100%
浏览 1633
已采纳

socket 帮忙改错 客户端关闭的时候不要让程序崩

我之前没说清楚 怪我...
图片说明
图片说明
图片说明

我想让客户端给服务器发送CLOSE,然后服务器关闭和这个客户端的连接。 但是只要一输入CLOSE 客户端那边都运行不了 更不要说发送给服务器 感觉是一个很简单的问题 但是一直调不通

只要有一个客户端退出 剩下的程序整个崩 有没有办法加几条语句让剩下的客户端和服务器正常运行

服务器



@RestController
@RequestMapping("/Socket")
@Api("服务器")
@Service
public class SocketService {
    @Autowired
    SetDao setDao;

//    SendData send=new SendData();
    static Scanner input = new Scanner(System.in);
    static List<Socket> list = new ArrayList();
    static Integer count =0;
    public static final Integer PORT=8888;

    @RequestMapping(value = "/photo", method = RequestMethod.POST)
    public String photocontrol(@RequestBody Integer e) throws IOException{
        SendData send=new SendData();
        if(e%2==0)
            send.msg="OPENPHOTO";
        else if(e%2==1)
            send.msg="CLOSEPHOTO";
        return "SUCCESS_PHOTO";
    }

    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public  void createServerSocket(){
//    {
        try {
            //创建服务器
            ServerSocket server = new ServerSocket(PORT);
            System.out.println("***服务器即将启动***");
            while (true) {
                Socket s = server.accept();
                list.add(s);
                System.out.println("当前客户端的数量为:" + (count + 1));
                //发信息(有多个客户端)
                if (count == 0) {
                    new SendData().start();
                }
                //收信息
                new GetData(new DataInputStream(list.get(count).getInputStream())).start();
                count++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
//    }
    }

    //给客户端发送信息
    public static class SendData extends Thread {
        private DataOutputStream dOutput;
        public static String msg;
        @Override
        public void run() {
            while (true) {
                try {
//                  String msg =input.next();
                    if (msg!=null) {
                        for (Socket socket : list) {
                            dOutput = new DataOutputStream(socket.getOutputStream());
                            dOutput.writeUTF(msg);
                        }
                        msg=null;
                    }
                } catch (IOException e) {
//                    break;
                    e.printStackTrace();
                }
            }
        }
    }

    //读取客户端发来的信息
    public static class GetData extends Thread {
        private DataInputStream dInput;
        public GetData(DataInputStream _dInput) {
            dInput=_dInput;
        }
        @Override
        public void run() {
            while (true) {
                try {
                    String msg = dInput.readUTF();
                    if (msg != null) {
                        System.out.println("客户端:"+ msg);
//                       if(msg.equals("CLOSE")) {
//                            dInput.close();
//                            list.remove(count);
//                            count--;
//                            System.out.println("当前客户端的数量为:"+count);
//                        }
//                        if(socket.getKeepAlive()==false){
//                            ((Reader)in).close();
//                            temp="客户端"+socket.getPort()+"退出";
//                            ss.appendMessage(temp);
//                            socket.close();
//                            this.stop();

                    }
                } catch (IOException e) {
                    try {
                        dInput.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    break;
                }
            }
        }
    }

}

客户端



@RestController
@RequestMapping("/TestSocket")
@Api("客户端")
@Service
public class TestSocketService {
    static Scanner input = new Scanner(System.in);
    public static final Integer PORT=8888;

    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public void createSocket() throws IOException {
        Socket socket = new Socket("localhost",PORT);
        System.out.println("已连接服务器");

        new GetData(new DataInputStream(socket.getInputStream())).start();
        new SendData(new DataOutputStream(socket.getOutputStream())).start();
    }

    //读取服务器发来的信息
    public static class GetData extends Thread {
        private DataInputStream dInput;
        public GetData(DataInputStream _dInput) {
            dInput = _dInput;
        }
        @Override
        public void run() {
            while (true) {
                try {
                    String msg = dInput.readUTF();
                    if (msg != null) {
                        System.out.println("服务器:" + msg);

                    }
                } catch (IOException e) {
                    try {
                        dInput.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    break;
                }
            }
        }
    }

    //给服务器发送信息
    public static class SendData extends Thread {
        private DataOutputStream dOutput;
        public SendData(DataOutputStream _dOutput) {
            dOutput = _dOutput;
        }
        @Override
        public void run() {
            while (true) {
                try {
                    System.out.println("给服务器发消息:");
                    String msg =input.next();
                    if (msg != null) {
                        dOutput.writeUTF(msg);
                    }
                } catch (IOException e) {
                    break;
//                    e.printStackTrace();
                }
            }
        }
    }
}
  • 写回答

5条回答

  • 浪里渔夫 2017-11-28 06:42
    关注

    上面给你回答了一次,没想到还是没解决你的问题哈,看你补充的提问,我又自己测试了下,找到了问题的原因。希望你能采纳。

    首先说下你这个错误的原因:多个线程同时操作一个Scanner(看下面代码,你定义的是静态的),而这个Scanner又是个非线程安全的类。这就导致了多线程抢占同一资源,最终引起了不可预测的异常。
    static Scanner input = new Scanner(System.in);

    一个Scanner只能对应一个客户端,所以如果你要测试多个客户端的话,你需要启动多个进程去测试,而不是在一个进程里启动多个线程。
    另外,在eclipse里的话,如果你启动多次main方法,他是有多个输入窗口的,每个scanner对应一个窗口。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)