简体   繁体   English

发送实时流数据时套接字连接丢失

[英]Socket connectivity loss when sending live streaming data

I'm struggling here... 我在这里苦苦挣扎...

I'm trying to determine if data was successfully sent to the server through a TCP socket using the OutputStream object. 我试图确定是否已使用OutputStream对象通过TCP套接字成功将数据发送到服务器。 For testing on emulator socket communications is loss after 30 sec. 对于仿真器套接字通信的测试在30秒后丢失。 For write data OutputStream.write(); 用于写入数据OutputStream.write(); its doesn't throw an exception , and local server continuously running its not crashing, only tcp socket connection is loss after some time. 它不会引发异常,并且本地服务器连续运行不会崩溃,只有tcp套接字连接在一段时间后会丢失。 All the methods in the socket class return as though the socket is active and working. 套接字类中的所有方法都将返回,好像套接字处于活动状态且正在工作。 Is there anything I'm doing wrong here? 我在这里做错什么吗? Is there any socket implementation or stream implementation I can use to get an exception or error when the stream/ socket doesn't actually send the data in the buffer? 当流/套接字实际上没有在缓冲区中发送数据时,是否可以使用任何套接字实现或流实现来获取异常或错误? Also setting setSoTimeout() on the socket doesn't seem to do anything. 同样在套接字上设置setSoTimeout()似乎没有任何作用。

Please guide me... 请指导我...

Here is my code: 这是我的代码:

private void sendRec() {
    int lstream;
    int port = 1012;
    byte[] byterecv = new byte[1040];

    while (true) {
        System.out.println("POOL-2");
        synchronized (recSendThread) {
            try {
                recSendThread.wait(20);
            } catch (InterruptedException e) {
            }
        }

        if (stopcall == true) {
            // break;
        }

        try {
            // Provides a client-side TCP socket
            Socket clientRec = new Socket();

            // serverSocket = new ServerSocket(port);
            // serverSocket.setSoTimeout(5000);

            // Connects this socket to the given remote host address and
            // port
            clientRec.connect(new InetSocketAddress("192.168.1.36", port));

            System.out.println("Just connected to "
                    + clientRec.getRemoteSocketAddress());
            System.out.println("SENTS Rec BEFORE");

            // output streams that write data to the network
            OutputStream outToServerRec = clientRec.getOutputStream();
            DataOutputStream outStreamRec = new DataOutputStream(
                    outToServerRec);

            outStreamRec.write(bData);
            System.out.println("SENTS Rec AFTER");

            // input streams that read data from network
            InputStream inFromServerRec = clientRec.getInputStream();
            // clientRec.setSoTimeout(5000);
            DataInputStream inStreamRec = new DataInputStream(
                    inFromServerRec);
            while ((lstream = inStreamRec.read(byterecv)) != -1) {
                System.out.println("startrec bytearray -- "
                        + byterecv.length);
                bos1.write(byterecv, 0, lstream);
            }

            inStreamRec.close();// for closing dataouputstream
            clientRec.close();// for closing socket connection
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}





Here is my receiver and player code..



  /**
   * start receiving the voice data from server
   * */
       protected void startplay() {
    System.arraycopy(frndid, 0, playByteData, 0, 4);
    System.arraycopy(userid, 0, playByteData, 4, 4);

        ByteBuffer.wrap(sessionid).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer().
            put(call_sessionid);
    System.arraycopy(sessionid, 0, playByteData, 8, 4);
    int lstream;
    int port = 1014;
    while (true) {
        System.out.println("POOL-3");
        try {
            if (stopcall == true) {
                System.out.println("BREAKEDDDD1111");
                //break;
            }
            // Host name
            // port++;
            InetAddress addressPlay = InetAddress.getByName("192.168.1.36");
            // Creates a new streaming socket connected to the target host
            Socket clientPlay = new Socket(addressPlay, port);
            System.out.println("Just connected to play : " + 
                                                clientPlay.getRemoteSocketAddress());
            System.out.println("SENTS Play BEFORE");

            // output streams that write data

            OutputStream outToServer = clientPlay.getOutputStream();
            DataOutputStream outStreamPlay = new DataOutputStream(outToServer);
            outStreamPlay.write(playByteData);


            System.out.println("SENTS Play after");

            // input streams that read data
            InputStream inFromServerPlay = clientPlay.getInputStream();
            DataInputStream inStreamPlay = new DataInputStream(inFromServerPlay);
            //clientPlay.setSoTimeout(5000);
            while ((lstream = inStreamPlay.read(byteArray)) != -1) {
                System.out.println("startplay() bytearray -- " + 
                                                          byteArray.length);
                bos.write(byteArray, 0, lstream);
            }

            inStreamPlay.close();
            clientPlay.close();// for closing play socket connection

            responseBuffer = bos.toByteArray();
            System.out.println("BAOSSIZE " + bos.size());
            bos.reset();
            bos.flush();
            bos.close();
            playing = true;
            System.out.println("res length -- " + responseBuffer.length);
            rcvbb=ByteBuffer.wrap(responseBuffer).order(ByteOrder.LITTLE_ENDIAN).
                                                    asShortBuffer().get(playShortData);

              playVoiceReceived();// plays received data

            } catch (ParseException e) {
            e.printStackTrace();
            } catch (IOException e) {
            e.printStackTrace();
        }
    }
    }

  /**
   * start playing received the voice data from server
    * */
     public void playVoiceReceived() {

    System.out.println("POOL-4");
      try {
        if (at != null) {
            if (at.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
                at.play();// starts playing
            } else {
                System.out.println("Play BEFORE WRITE");
                // Writes the audio data to the audio hardware for playback.
                at.write(playShortData, 0, BufferElements2Play);
                System.out.println("Play AFTER WRITE");
                at.flush();
            }
        }
          } catch (Exception e) {
        e.printStackTrace();
      }
    }

The socket has sent the data ... to the local socket send buffer. 插座发送的数据......到本地套接字发送缓冲区。 What happens after that is up to the local TCP stack, the network, the remote TCP stack, and the remote application. 此后将发生什么,取决于本地TCP堆栈,网络,远程TCP堆栈和远程应用程序。 If you want to know whether the remote application got the data, it will have to send you a reply. 如果您想知道远程应用程序是否获取了数据,则必须向您发送回复。

Operator write does not check whether data was delivered because otherwise it would have to wait for too long time. 操作员write操作不会检查数据是否已传送,因为否则将不得不等待太长时间。 If network connection is actually down, TCP layer of operating system, will try to send data anyway, but will detect problems somewhat later, ie 1 minute later, because it will not receive acknowledgement messages from the opposite side. 如果网络连接实际上已断开,则操作系统的TCP层将尝试尝试发送数据,但是将在稍后(即1分钟后)检测到问题,因为它将不会收到来自另一侧的确认消息。 It will then try to resend data several times, see that problem persists and only then will report exception condition on the socket. 然后它将尝试重新发送数据几次,看到问题仍然存在,然后才会在套接字上报告异常情况。 To know that socket is in exception condition, you need to perform some operator on socket, ie another write attempt. 要知道套接字处于异常状态,您需要对套接字执行一些操作,即另一次写尝试。 Try doing write in a loop like this: 尝试像这样在循环中执行写操作:

while (true) { outStreamRec.write (data); while(true){outStreamRec.write(data); Thread.sleep (1000L); Thread.sleep(1000L); } }

It should throw an error about 2 minutes after network will be down. 网络关闭后约2分钟,它应该引发错误。

Note, that in opposite to write operation, operation connect is synchronous, so it actually waits for response from the opposite side, and if there is not respose, it will throw an exception. 请注意,与write操作相反,操作connect是同步的,因此它实际上等待来自另一端的响应,如果没有重新放置,它将抛出异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM