使用socket读取服务器发送的数据问题

刚刚项目使用到socket进行数据的传送,其中数据的读取问题着实
费了老大的劲,以此分享希望能让有缘人少走弯路。

new Thread() {
            @Override
            public void run() {
                try {
                    mSocket = new Socket(SERVICEADD, DST_PORT);
                    //设置socket读取数据流的超时时间
                    mSocket.setSoTimeout(5000);
                    mSocket.setTcpNoDelay(true);
                    //设置客户端close()方法起作用时延时30s关闭socket
                    mSocket.setSoLinger(true, 30);
                    mSocket.setSendBufferSize(4096);
                    //防止服务器端无效时,客户端长时间处于连接状态
                    mSocket.setKeepAlive(true);
                    OutputStream ou = mSocket.getOutputStream();
                    //向服务器发送要查询的数据
                    ou.write(queryContent.getBytes());
                    ou.flush();
                    //读取发来服务器信息
                    BufferedReader br = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
                    List<QueryDatas> queryDatases = QueryFomart.formatSocketString(br);
                    EventBus.getDefault().post(queryDatases);
                    br.close();
                    mSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

对于使用readLine读取数据的一个问题就是,无法走到while后面去,究其原因:

1.误以为readLine()是读取到没有数据时就返回null(因为其它read方法当读到没有数据时返回-1),而实际上readLine()是一个阻塞函数,当没有数据读取时,就一直会阻塞在那,而不是返回null;因为readLine()阻塞后,System.out.println(message)这句根本就不会执行到,所以在接收端就不会有东西输出。要想执行到System.out.println(message),一个办法是发送完数据后就关掉流,这样readLine()结束阻塞状态,而能够得到正确的结果,但显然不能传一行就关一次数据流;另外一个办法是把System.out.println(message)放到while循环体内就可以。

2.readLine()只有在数据流发生异常或者另一端被close()掉时,才会返回null值。

3.如果不指定buffer大小,则readLine()使用的buffer有8192个字符。在达到buffer大小之前,只有遇到”/r”、”/n”、”/r/n”才会返回。

小结,使用readLine()一定要注意:

1、读入的数据要注意有/r或/n或/r/n
2、没有数据时会阻塞,在数据流异常或断开时才会返回null
3、使用socket之类的数据流时,要避免使用readLine(),以免为了等待一个换行/回车符而一直阻塞
4、或者是服务器端在发送完数据就进行关闭

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在计算机网络中,Socket是一种在应用程序中进行网络通信的一种方法。它可以用于发送和接收服务器返回的数据。 首先,我们需要在客户端代码中创建一个Socket对象,该对象用于与服务器建立连接。我们可以指定服务器的IP地址和端口号来建立连接。然后,我们使用Socket对象的send()方法发送数据到服务器。 发送数据后,我们需要等待服务器进行处理并返回响应。为了接收服务器返回的数据,我们可以使用Socket对象的recv()方法。这个方法将会阻塞程序的执行,直到接收到数据为止。 接收到服务器返回的数据后,我们可以对数据进行处理。可以通过解析服务器返回的数据获取所需的信息。处理完返回的数据后,我们可以根据需要再次使用Socket对象的send()方法发送新的数据到服务器,或者关闭Socket。 在使用Socket进行数据的发送和接收时,需要注意以下几点: 1. 确保客户端与服务器之间的网络连接是可靠的。如果连接断开,可以尝试重新建立连接。 2. 建立连接时,要确保服务器的IP地址和端口号是正确的,否则将无法成功建立连接。 3. 在发送数据时,要根据服务器的要求进行数据格式的设置,确保数据可以被服务器正确解析。 4. 在接收服务器返回的数据时,要根据服务器返回数据的格式进行解析,并注意处理可能出现的异常情况。 总之,使用Socket发送并接收服务器返回的数据是一种常见的网络通信方式,它可以实现客户端与服务器之间的数据交互。掌握Socket使用方法,可以帮助我们更好地理解和开发网络应用程序。 ### 回答2: Socket是一种用于在网络间进行通信的工具。在客户端发送请求并接收服务器返回的数据时,可以通过以下步骤完成: 1. 创建Socket对象:首先需要在客户端创建一个Socket对象,用于与服务器进行通信。可以指定服务器的IP地址和端口号来建立连接。 2. 连接服务器:通过调用Socket对象的connect()方法来连接到服务器。如果连接成功,客户端可以发送请求给服务器。 3. 发送数据使用Socket对象的输出流来发送数据给服务器。可以使用write()方法将数据写入输出流。 4. 接收数据使用Socket对象的输入流来接收服务器返回的数据。可以使用read()方法从输入流中读取数据。 5. 处理数据:客户端可以根据需求对接收到的数据进行处理。可以将数据转换成字符串或者其他格式,以便进一步操作或显示。 6. 关闭连接:当所有数据处理完毕后,可以调用Socket对象的close()方法关闭连接。这会释放资源并且断开与服务器的连接。 以上就是通过Socket发送并接收服务器返回的数据的基本过程。在实际应用中,还需要处理异常、设计协议等其他方面的问题来确保通信的稳定和安全。 ### 回答3: 使用socket发送数据并接收服务器返回的数据,需要经过以下几个步骤: 1. 创建一个socket对象,可以使用Python的socket模块的socket()函数来创建。例如: ``` import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ``` 2. 连接到服务器。使用socket对象的connect()方法来连接服务器。参数是一个元组,包含服务器的IP地址和端口号。例如: ``` s.connect(('服务器IP地址', 端口号)) ``` 3. 发送数据到服务器。通过socket对象的send()方法来发送数据。参数是一个字符串,需要先将字符串转换成字节类型。例如: ``` data = '发送的数据' s.send(data.encode()) ``` 4. 接收服务器返回的数据使用socket对象的recv()方法来接收数据。可以设置接收的数据大小。例如: ``` recv_data = s.recv(1024) ``` 其中,1024表示最多接收的字节数。 5. 关闭socket连接。使用socket对象的close()方法来关闭连接。例如: ``` s.close() ``` 通过以上步骤,可以使用socket实现发送数据并接收服务器返回的数据。根据实际需求,可以在发送和接收数据的过程中进行逻辑处理和错误处理,以实现更完善的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值