使用TCP套接字而不使用缓冲区 [英] Using TCP socket without using a buffer

查看:75
本文介绍了使用TCP套接字而不使用缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

非常感谢您的回复.我需要重新表述我的问题...充当TCP服务器的设备以连续方式发送数据,因为它是封闭的设备,因此我无法修改任何TCP服务器参数.为了处理它,我必须连续地在某个地方接收和存储此数据,与此同时,我必须继续接收服务器数据,因为我不会丢失服务器消息的任何部分.

然后,我有两件事要做:我必须接收和存储(例如在数组中)连续的数据流,同时我需要读取接收到的数据以对其进行处理.服务器将永远不会停止发送数据,而我必须捕获所有已发送的数据.

这就是我问是否有一种方法可以不依赖字节缓冲区来接收TCP客户端中的数据,是否有一种方法可以连续获取所有数据而不丢失任何数据流. br/>
再次感谢!

-------------------------------------------------- --------

您好:

我在我的应用程序中使用TCP客户端套接字.在这种情况下,我需要从连续发送消息的设备(作为TCP服务器)接收数据,而无需在发送之前指定发送数据的长度,这就像二进制数据流一样.我需要读取此数据并处理消息的某些特定部分.我发现有关接收TCP数据的最常见引用是使用Stream Read方法,但是此方法需要定义一个已定义大小的缓冲区.请在下面阅读我的代码:


Thanks so much for replying. I need to reformulate my question... The device that function as TCP server sends data in continuous manner, because is a closed device I cannot modify any TCP server parameters. I have to receive and storage this data somewhere continuosly in order to process it, in the meantime I need to keep receiving the server data because I cannot lose any part of the server messages.

Then I have two things to do: I must to receive and storage (in an array for example) a continuous data flow, at the same time I need to read the received data to process it. The server will never stop to send data and I have to catch all the sent data.

That´s the reason I asked if there´s a way to not depend of a byte buffer to recieve data in TCP client, if there´s a way to get all the data continuosly to storage it without losing any part of the data flow.

Thanks again!

----------------------------------------------------------

Hello:

I´m using TCP client socket in my app. In this case I need to receive data from a device (that is working as TCP server) that is continuosly sending messages without specifying the lenght of the sent data before sending it, it´s like a streaming of binary data. I need to read this data and process some specific parts of the message. The most common references I found about receiving TCP data is using the Stream Read method, but this method requires to define a buffer of defined size. Please read my code below:


Imports System.IO
Imports System.Net.Sockets
Imports System.Threading
Imports System.Net
Imports System.Text

Public Class Write
    Public Event DataRecieved(ByVal data As String)
    Private Stm As Stream
    Private tcpThd As Thread


    Public Sub ConnectToServer()
        Try
            Dim tcpClnt As New TcpClient
            tcpClnt.Connect(IPAddress.Parse("192.168.1.50"), 2111)
            Stm = tcpClnt.GetStream()
            tcpThd = New Thread(AddressOf ReadSocket)
            tcpThd.Start()
        Catch ex As Exception
            MsgBox(ex.Message)
            Exit Sub
        End Try

    End Sub

#Region "Private Methods"
    Private Sub ReadSocket()
        Dim Buffer() As Byte
        While True
            <b>Buffer = New Byte(4000) {}</b>
            <b>Stm.Read(Buffer, 0, Buffer.Length)</b>
            DataRecieved(Encoding.ASCII.GetString(Buffer))
        End While
    End Sub
#End Region
End Class



您可以发现,如果我定义了4000字节的缓冲区,那么我只会读取设备发送的4000字节数据,但是设备一直都在发送数据,因此我也需要一直读取数据,而不仅仅是4000字节...有没有办法一直读取数据并在收到数据的那一刻就对其进行处理?

在此先感谢.



You can figure that if I define a buffer of 4000 bytes, I read just 4000 bytes of data sent by the device, but the device keep sending data all the time and I need to keep reading data all the time too, not just 4000 bytes... Is there a way to read data all the time and process this data at the very moment it is received?

Thanks in advance.

推荐答案

>>为了处理它,我必须连续地在某个地方接收和存储此数据,与此同时,我必须继续接收服务器数据,因为我不会丢失服务器消息的任何部分.

套接字将为您缓冲数据,直到您读取为止,但是如果缓冲区已满,它将开始丢弃消息.您需要确保经常阅读,以使套接字不必丢弃任何东西.换句话说,您需要保持循环读取状态(如您所做的那样),并且不允许处理数据以阻止从套接字读取数据.我想您已经基于以下陈述意识到了这一点:

>>如果有一种方法可以连续获取所有数据,而又不会丢失任何数据流的话

要解决这一部分:

>>是否有一种不依赖字节缓冲区的方式

不,套接字发送和接收字节.如果要直接处理套接字,则必须处理byte [].但这不是代码的问题,而是在与危险的读取相同的线程上处理数据.根据要花费多长时间来备份数据以等待读取,这就是您要避免的事情.服务器可能不经常发送数据和/或解析它不会花费很长时间,在这种情况下,您会保持现状.

如果不是这种情况,那么我认为您将不得不在另一个线程上进行数据处理.确切的操作方式取决于您的应用程序的具体情况.您可能不想要做的是为收到的每条消息启动一个新线程;相反,您很可能希望使用一个线程来处理每条消息.这样一来,每次处理一条消息的时间就会按照收到的顺序进行处理.如果这些无关紧要,则可以为每个消息启动一个线程(仍然可能不是最佳选择),或者使用线程池为您处理线程(可能比手动线程更好).

无论采用哪种方法,
>> I have to receive and storage this data somewhere continuosly in order to process it, in the meantime I need to keep receiving the server data because I cannot lose any part of the server messages.

The socket will buffer data for you until you read it, but if the buffer becomes full it''ll start dropping messages. You need to make sure that you keep reading frequently enough so that the socket doesn''t have to discard anything. In other words, you need to keep reading in a loop (as you''re doing) and not allow processing the data to block reading the data from the socket. I think you realize this already, based on this statement:

>> if there´s a way to get all the data continuosly to storage it without losing any part of the data flow

To address this part:

>> if there´s a way to not depend of a byte buffer

no, sockets send and receive bytes. If you want to deal directly with sockets then byte[]s are what you have to deal with. That''s not the problem with your code, though, it''s the processing the data on the same thread as the read that looks dangerous. Depending on how long that takes data could be backing up waiting to be read and that''s what you want to avoid. It may be the case that the server doesn''t send data frequently and/or parsing it doesn''t take very long in which case you''ll be fine as is.

If that''s not the case then one way or another I think you''re going to have to do the data processing on another thread. Exactly how you do that depends on the specifics of your application. What you probably don''t want to do is start a new thread for every message that''s received; instead you most likely want one thread that handles every message. This will make it so that each message is handled one at a time and they''re handled in the order that they''re received. If those things don''t matter then you could either start a thread for each message (still may not be optimal) or use the Thread Pool to handle the threads for you (probably better than manual threading).

With either approach, the
while 
{ 
    read; 
    process; 
}


循环将更改为


loop will change to

while
{
    read;
    send data to another thread for processing;
}


这样,执行读取操作的线程将不会花费任何时间在处理上,并且可以继续从套接字读取数据.还有其他一些事情要考虑:
*围绕从套接字读取的代码的异常处理-当前尚无
*进行读取和解析的线程如何干净地退出?读取线程的写入方式是没有办法的.
*如何从读取线程到处理线程获取数据?您将需要阅读有关线程安全性,等待句柄和其他常规线程主题的信息(例如 [ ^ ]).或发布另一个问题寻求帮助.
*您的每次阅读确实给您解析了一条完整的消息,还是您可能需要将从多次读取中获得的数据合并为一条完整的消息?还是一次阅读会给您多个消息以一次全部解析?
*为什么为什么一个读取数据的类称为Write?


That way the thread doing the reading won''t spend any time on processing and can continue reading data from the socket. There are still some other things to consider:
* exception handling around the code that reads from the socket - currently there is none
* how do the threads doing the reading and parsing exit cleanly? The way that read thread is written there isn''t a way.
* how are you going to get data from the read thread to the processing thread? You''ll want to read up on thread safety, wait handles and other general threading topics (like this[^]). Or post another question asking for help on that.
* does each read you do give you one full message to parse, or might you need to combine the data received from multiple reads into one full message? Or will one read give you multiple messages to parse all at once?
* why is a class that reads data called Write?


即使您使用的是十亿字节的缓冲区,也没关系.在一次接收中,您不会完全得到整个缓冲区.如果您担心4000字节不足以传递整个消息,则可以编写一个4字节的数据包来表示预期缓冲区的大小,并相应地声明它(然后进行迭代,直到获得整个缓冲区) .您可能会发现跟踪缓冲区中的进度也很有用.您可以(并且必须)知道每次迭代中的读取字节数,Read函数将返回它.
Even if you were using a buffer of billion bytes, it doesn''t matter. In one receive you won''t get exactly the whole buffer. If you are worried that 4000 bytes are not sufficient for the whole message to pass, you could write a 4-bytes packet that would represent the size of the expected buffer and declare it accordingly (and then iterate until you would get the whole buffer). You might find it useful also to track the progress within the buffer. You can (and must) know the number of read bytes in every iteration, the Read function returns it.


这篇关于使用TCP套接字而不使用缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆