Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在TCP客户机中读取未知数据长度_C#_Tcp_Bytearray_Tcpclient - Fatal编程技术网

C# 如何在TCP客户机中读取未知数据长度

C# 如何在TCP客户机中读取未知数据长度,c#,tcp,bytearray,tcpclient,C#,Tcp,Bytearray,Tcpclient,我是C#的新手。在我的TCP客户端中,具有以下功能,可将数据发送到服务器并返回响应: private static TcpClient tcpint = new TcpClient(); //Already initiated and set up private static NetworkStream stm; //Already initiated and set up private static String send(String data) {

我是C#的新手。在我的TCP客户端中,具有以下功能,可将数据发送到服务器并返回响应:

private static TcpClient tcpint = new TcpClient(); //Already initiated and set up
private static NetworkStream stm;                  //Already initiated and set up

private static String send(String data)
{
    //Send data to the server
    ASCIIEncoding asen = new ASCIIEncoding();
    byte[] ba = asen.GetBytes(data);
    stm.Write(ba, 0, ba.Length);

    //Read data from the server
    byte[] bb = new byte[100];
    int k = stm.Read(bb, 0, 100);

    //Construct the response from byte array to string
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < k; i++)
    {
        sb.Append(bb[i].ToString());
    }

    //Return server response
    return sb.ToString();
}

如果来自服务器的响应超过100字节,我该怎么办?在不知道服务器数据的最大长度的情况下,如何读取数据?

通常,在没有特定内在大小的情况下,tcp协议会显式发送它们发送的对象的长度。一种可能的说明方法:

size_t data_len = strlen(some_data_blob);
char lenstr[32];
sprintf(lenstr, "%zd\n", data_len);
send(socket, lenstr, strlen(lenstr));
send(socket, some_data_blob, data_len);
然后,当接收器读取长度字符串时,它确切地知道应该如何处理mush数据(良好的编程实践是信任但验证——如果确实有更多或更少的数据发送——比如说由“邪恶的参与者”——您需要准备好处理这些数据)。

不是关于C,而是关于编写TCP应用程序的一般答案:

TCP是基于steam的协议。它不维护消息边界。因此,使用TCP的应用程序应该注意在服务器和客户端之间选择正确的数据交换方法。如果在一个连接上发送和接收多条消息,它就变得更加重要

一种广泛使用的方法是在数据消息前加上长度字节

例:

[2字节长度字段][实际数据]

此类数据的接收者(无论是服务器还是客户端)需要解码长度字段,等待接收到尽可能多字节的事件发生,或者在超时时发出警报并放弃

另一个可以使用的协议是让应用程序维护消息边界

例: `[消息开始][实际数据][消息结束]


接收器必须解析起始字节和结束字节(由应用程序协议预定义)的数据,并将两者之间的任何内容视为感兴趣的数据。

您好,我用一个列表解决了这个问题,我不知道完整包的大小,但我可以部分读取它

List<byte> bigbuffer = new List<byte>();

byte[] tempbuffer = new byte[254]; 
//can be in another size like 1024 etc.. 
//depend of the data as you sending from de client
//i recommend small size for the correct read of the package

NetworkStream stream = client.GetStream();

while (stream.Read(tempbuffer, 0, tempbuffer.Length) > 0) {

    bigbuffer.AddRange(tempbuffer);
} 

// now you can convert to a native byte array
byte[] completedbuffer = new byte[bigbuffer.Count];

bigbuffer.CopyTo(completedbuffer);

//Do something with the data
string decodedmsg = Encoding.ASCII.GetString(completedbuffer);
List bigbuffer=newlist();
字节[]临时缓冲区=新字节[254];
//可以是其他尺寸,如1024等。。
//取决于从de客户端发送的数据
//我建议使用小尺寸,以便正确阅读包装
NetworkStream=client.GetStream();
while(stream.Read(tempbuffer,0,tempbuffer.Length)>0){
AddRange(tempbuffer);
} 
//现在可以转换为本机字节数组
byte[]completedbuffer=新字节[bigbuffer.Count];
CopyTo(completedbuffer);
//对数据做点什么
string decodedmsg=Encoding.ASCII.GetString(completedbuffer);

我使用图像进行此操作,看起来不错,我认为如果读取的是未知大小的完整源文件,您不知道数据的大小。我正在四处寻找答案,发现Available属性已添加到TcpClient。它返回可读取的字节数

我假设它是在大多数回复之后添加的,所以我想把它分享给其他可能偶然发现这个问题的人


您可以在发送数据之前发送数据长度,也可以使用数据中不存在的分隔符字符data@L.B哦,好吧,这有点道理。所以我有两个读取操作。第一个将获取数据长度。第二个将基于第一个读取操作中给定的长度获取实际数据。对吗?但是,如果字符串不符合在换行符中,使用
var reader=new StreamReader(tcpint.GetStream());
将更容易(在另一端也是
StreamWriter
),这样,您只需执行
reader.ReadLine()
writer.WriteLine()
太棒了!非常有意义!可以接收tcpclient对象的buffersize属性
List<byte> bigbuffer = new List<byte>();

byte[] tempbuffer = new byte[254]; 
//can be in another size like 1024 etc.. 
//depend of the data as you sending from de client
//i recommend small size for the correct read of the package

NetworkStream stream = client.GetStream();

while (stream.Read(tempbuffer, 0, tempbuffer.Length) > 0) {

    bigbuffer.AddRange(tempbuffer);
} 

// now you can convert to a native byte array
byte[] completedbuffer = new byte[bigbuffer.Count];

bigbuffer.CopyTo(completedbuffer);

//Do something with the data
string decodedmsg = Encoding.ASCII.GetString(completedbuffer);