当前位置: 代码网 > it编程>编程语言>Java > Java-readLine()阻塞问题及解决过程

Java-readLine()阻塞问题及解决过程

2026年05月07日 Java 我要评论
socket编程中readline()阻塞问题readline()的api说明public string readline() throws ioexception中文版:读一行文字。 一行被视为由换

socket编程中readline()阻塞问题

readline()的api说明

  • public string readline() throws ioexception

中文版:

  • 读一行文字。 一行被视为由换行符(’\ n’),回车符(’\ r’)中的任何一个或随后的换行符终止。
  • 返回:包含行的内容的字符串,不包含任何行终止字符,如果到达流末尾,则为null

英文版:

  • reads a line of text. a line is considered to be terminated by any one of a line feed (’\n’), a carriage return (’\r’), or a carriage return followed immediately by a linefeed.
  • returns:
  • a string containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

遇到的问题:

  • 当使用socket写一个双向通信的服务端时,总是接收不到来自用户的消息,和书上比对才发现是readline()的问题,
  • 还有就是客户端和服务端的初始状态问题(一个为初始为“发送”,一个为“接收”)

第一种情况

  • 一个客户端,一个服务端。当服务端使用readline()读消息时,需要读到一个换行符(‘\n’,或’\r’)才会结束。否则回一直阻塞,主线程就挂在这儿了
  • 解决方法:在客户端发送消息的时候,外加一个换行符
//用户发送消息的线程
class sentmessage extends thread{
        private socket socket;
        private bufferedwriter bw;
        private bufferedreader mysc;
        sentmessage(socket socket){
            this.socket = socket;
            try {
                bw = new bufferedwriter(new outputstreamwriter(client.getoutputstream()));
                mysc = new bufferedreader(new inputstreamreader(system.in));
            } catch (ioexception e) {
                e.printstacktrace();
            }
        }
        @override
        public void run(){
            try{
                while (true){
                    string mymessage = mysc.readline();
                    bw.write(mymessage+"\n");
                    bw.flush();
                    if("bye".equals(mymessage)){
                        break;
                    }
                }
            }catch (ioexception e){
                e.printstacktrace();
            }finally {
                try{
                    if(mysc!=null){
                        mysc.close();
                    }
                    if(bw!=null){
                        bw.close();
                    }
                }catch (ioexception e){
                    e.printstacktrace();
                }
            }
        }
    }

第二种

  • 当用服务器转发来自每个用户的消息到聊天室时,如果就用一个"转发消息"方法也会出现问题,就是使用了readline()的阻塞
  • 思考:一个客户都应有一个自己”转发消息“通道(线程),不和其他客户共用一个”转发通道“(会导致阻塞
  • 解决,用一个线程来做转发
//内置线程类用于接收消息,并广播
    class acceptmessage extends thread{
        private socket clientsocket;
        private bufferedreader br;
        acceptmessage(socket clientsocket){
            this.clientsocket = clientsocket;
        }
        /**
         * 服务器将所有接收的消息广播(显示在每一个客户的聊天窗口中
         * 注意:如果这里不用线程,会出现问题,思考---其实就是readline()阻塞的问题
         */
        private void telleveryone(socket socket){
            try{
                //先从发送消息的客户读内容
                br = new bufferedreader(new inputstreamreader(socket.getinputstream()));
                string message = br.readline();
                chatarea.append("用户"+socket.getport()+": "+message+"\n");
                //然后将内容广播到每一个客户接口
                iterator<socket> it = list.iterator();
                while (it.hasnext()){
                    socket socket2 = it.next();
                    //对自己就不要广播了
                    if(socket!=socket2){
                        bw = new bufferedwriter(new outputstreamwriter(socket2.getoutputstream()));
                        bw.write(socket2.getinetaddress().gethostaddress()+": "+message+"\n");
                        bw.flush();
                    }
                }
            }catch (ioexception e){
                e.printstacktrace();
            }
        }
        @override
        public void run(){
            while (true){
                //接收并广播
                telleveryone(clientsocket);
            }
        }
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com