问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Java Socket开发 关于报文传递和接收

发布网友 发布时间:2022-04-22 06:22

我来回答

1个回答

热心网友 时间:2023-05-28 14:40

看 Oracle 官方教程,同步式的 Socket 就是传统的一问一答方式,它就是你需要的。

客户端先 socket.getOutputStream().write(...); 之后到 socket.getInputStream().read(byte[]) 在循环中读取直到 read 方法返回 -1 或你期望的字节数已经全部收到了就停下来,如果不尝试停下来,后面的 read 将会阻塞等待。


http://docs.oracle.com/javase/tutorial/networking/sockets/index.html


基于性能改进,一般我们需要使用 NIO 异步的 socket,只需要一个线程负责通信,每个线程都有自己的出站消息队列和入站消息队列,以线程为 key 区分开,通信线程只负责把各自的消息从出站队列中发送去并把收到的消息放入入站队列中,应用程序线程就去各自的消息队列中取消息就可以了。因为每个应用线程有各自的消息队列,我们把消息放入出站队列之后就到入站队列上用同步锁等待的方法阻塞到有消息回答时为止。


关于 NIO non-blocking 非阻塞式 socket,下面有一个 NBTimeServer 例子,它讲的是服务端。客户端与此类似,

http://docs.oracle.com/javase/7/docs/technotes/guides/io/example/index.html


NIO 通信线程样例。

 

  public void run()
    {
        int tip = 0;
        try
        {
            selector = Selector.open();
            SelectionKey k = channel.register(selector, getInterestOptions());
            k.attach(thread); // 把当前线程绑定到附件中。

            this.running = true;
            statusChanged(Status.CONNECTED);
            while (this.isRunning())
            {
                // select() is a blocking operation.
                int eventCount = selector.select();
                debug("[MC.Debug] Polling TCP events ... " + eventCount);
                if (eventCount > 0 && channel.isOpen() && this.isRunning())
                {
                    Set keys = selector.selectedKeys();
                    for (Iterator iter = keys.iterator(); iter.hasNext(); iter.remove())
                    {
                        SelectionKey key = (SelectionKey) iter.next();
                        Thread thread = (Thread) key.attachment();
                        
                        if (!key.isValid())
                        { // channel is closing.
                            break;
                        }
                        process(key); // 处理读取消息并把消息放入 thread 对应的队列。//写出消息类似的,不过在 register 时需要注册写出允许的事件,
                        
                    }
                }
            }
        }

追问非常感谢如此耐心并全面的回答.

还有一问在同步式的 Socket中用OutputStream 发送完报文后.是否需要关闭当前socket.
然后新开socket,调用 socket.getInputStream().read()方法来进行等待.

如果不关闭是否会造成阻塞?

追答发送完了不用关吧,读取完了再关才合适啊。你可以测试嘛。比如连接到一个像 oracle 这样的第三方服务器程序(不是你写的,免得服务器端有没有bug你还得确认)来测试你的客户端程序。

按理说 output stream 不应该影响 input stream 是否阻塞,因为现有的 Socket 基本上工作在全双式模式,也就是说收和发两个方向是互不干涉的,但如果我们尝试关闭就难说了,当然如果对方正在 read 时阻塞了而且它也我们一样地使用一问一答的方式当然可能会出现死锁的情况,因为我们不知道 Java 底层的功能是如何处理建立连接时的状态通知的,因此我们在所有事情处理完了再闭吧。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
帮帮忙写个英语作文80字的 谢谢 80年山东高考总分 总胆红素25.44(正常3.4-22),直接胆红素7.13(正常0-6.8... ...参考值 总胆红素 19.4 0-23.0 umol/L 直接胆红素 6.4 0-8.0 umol/... 蟹爪兰冬天多久浇水 冬季蟹爪兰浇水间隔需长达多久 蟹爪兰冬天什么时候浇水好 蟹爪兰冬天多久浇一次水 端午节一家人吃饭的说说 端午节跟谁一起过 端午节一家人聚在一起吃饭的说说 端午节是家人团聚吗 请问江苏省的权威精神鉴定机构是哪一家? 康黎医学的抑郁症基因检测适用于哪些类型的患者? java中socket不断接收数据问题 java 中怎样接收Socket(jsp页面显示)数据怎样解析... 南京精神病哪里治疗比较好? java 怎么获得socket流 小学四年级对老师的感恩祝福语 语文四年级上册21课金牌学案第三题怎么做.? 软件专利的申请方法及保护策略 小学四年级语攴成语组成有多少个 专利检索的软件有哪几款? 您好,我想要参考四年级下册的期末试卷。(语文数... 如何保护软件专利? 软件可以做发明专利吗?需要提供哪些材料 如何运用ppp模式加快智慧城市创新发展 资金来源如... 小学四年级语文下册第四单元口语交际 什么才是一个成熟智慧城市的标准 可以获取与软件相关的发明的专利吗? 双跨桥是什么意思 小学语文四年级下册 《冼星海和他的风》 主要内容 江苏省交通事故精神损害赔偿数额标准 java socket发送和接收多条数据的情况怎么解决 请问江苏省哪家医院精神科效果最好? 用JAVA写一个SOCKET 接收TCP发来的消息 请教大家JAVA——socket接收的数据(byte[])的处理 江苏精神对大学生意味着什么? java 中的socket 是不是从哪个端口发出客户端请求... 江苏高考体检受限条款24,25,26分别是什么? java如何用socket接受和发送数组 江苏精神分裂能治好吗? 华为手机与苹果手机综合比较,哪个更好? java接受c语言socket字符串 java Socket客户端实时接受信息回显页面 java 通过socket接收服务端的数据包,解析完成之后... java的serversocket怎么接受来自客户端的数据 java socket数据接收失败问题 2021年华为和苹果手机哪个更好 java socket 服务端接收数据阻塞。 java socket服务器怎么给客户端发信息 买华为与苹果哪个好用