如何通过tcp/ip协议发送包的长度

本文关键字:协议 何通过 tcp ip | 更新日期: 2023-09-27 17:50:32

我正在为我的一个学校项目做这个。我试图设计一个多线程服务器,接受客户端与数据库(添加,删除记录等)的工作。当我将客户端连接到服务器时,我想接收数据库中所有的学生。

我访问服务器端的数据库并将信息存储在ArrayList中,我试图通过网络发送它。我对XMLserializing没有任何知识,所以我试图将arrayList中的每个字符串发送到客户端。当我从服务器发送数据时,我有时会同时接收到所有数据,有时则不会,因此我的第一个猜测是,我必须将我发送的数据分成一定长度的包。我不知道如何在包装的开头加上长度。这不是一样的吗?也许我得到了正确的长度,也许没有。

这是我的代码;我还没有尝试发送每个包裹的长度,因为我不知道如何发送。我尝试从服务器发送数组列表的长度,并多次从网络流中读取,但它不工作(我在一个包中接收所有数据)。

服务器端:

private void HandleClient(object client)
    {
        try
        {
            ClientNo++;
            TcpClient tcpClient = (TcpClient)client;
            NetworkStream clientStream = tcpClient.GetStream();
            byte[] bytes = new byte[4096];
            int i;
            // Robot r = new Robot();
            Protocol p = new Protocol();
            ArrayList ListaStudentiResponse = p.ExecuteQueryOnStudents("select * from studenti");
            byte[] Length = new byte[4];
            Length = System.Text.Encoding.ASCII.GetBytes(ListaStudentiResponse.Count.ToString());
            clientStream.Write(Length, 0, Length.Length);
            foreach ( String s in ListaStudentiResponse)
            {
                byte[] data = System.Text.Encoding.ASCII.GetBytes(s);
                clientStream.Write(data, 0, data.Length);
            }

            tcpClient.Close();
            ClientNo--;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

On Client:

private void connectToServerToolStripMenuItem_Click(object sender, EventArgs e)
    {
        tcpclient = new TcpClient();
        NetworkStream netStream;
        try
        {
            tcpclient.Connect("localhost", 8181);
            netStream = tcpclient.GetStream();
            Byte[] bytes = new Byte[10000];
            int readBytes = netStream.Read(bytes, 0, bytes.Length);
             int Length  =Int32.Parse(Encoding.ASCII.GetString(bytes, 0, readBytes));
             MessageBox.Show(Length.ToString());
             int i = 0;
             while (i < Length)
             {
                i++;
                Byte[] b = new Byte[10000];
                readBytes = netStream.Read(bytes, 0, bytes.Length);
                String response = Encoding.ASCII.GetString(b, 0, readBytes);
                MessageBox.Show(response);

             }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}

如何通过tcp/ip协议发送包的长度

您可以使用StateObject来跟踪您的数据有多大,然后在ReadCallback期间进行测试,以查看您是否拥有"所有"消息。如果你没有得到所有的消息,你可以用当前的StateObject再次调用beginreceive。

下面是一个很好的例子:http://www.csharphelp.com/2007/02/asynchronous-server-socket-using-c/

这是我一直使用的:

如何在SocketAsyncEventArgs对象上使用缓冲区

看公认的答案。首先,这是在使用一种叫做完成端口的东西它比异步要高效得多。其次,我发现通过查看e.SocketError来找出故障的确切原因是非常容易的。

它是如何工作的,为您的消息发送,附加消息的标题和结尾。
因此,当它收到消息时,它将检查是否收到了预告片。如果没有接收到,它将继续为该客户端接收,并将接收到的消息附加到stringBuilder对象。一旦接收到预告片,只需调用stringbuilder.toString()来获取整个内容。