首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TCPListener文件传输

TCPListener文件传输
EN

Stack Overflow用户
提问于 2014-11-14 13:54:46
回答 1查看 1.7K关注 0票数 0

我遇到了一点小麻烦。

我可能不是TCP连接方面的专家,但我希望这里的人能帮助我。

这是我的客户代码:

代码语言:javascript
运行
复制
    void Connect(String server, String message)
    {
        try
        {
            Int32 port = 8968;
            TcpClient client = new TcpClient(server, port);
            Byte[] data = File.ReadAllBytes(curSelectedFile);
            NetworkStream stream = client.GetStream();


            Byte[] fileData = File.ReadAllBytes(curSelectedFile);
            Byte[] msgData = Encoding.ASCII.GetBytes("SendFile");
            Byte[] sendData = new byte[fileData.Length + msgData.Length];

            // Copy data to send package.
            msgData.CopyTo(sendData, 0);
            fileData.CopyTo(sendData, 4);

            // Send the message to the connected TcpServer. 
            stream.Write(data, 0, data.Length);

            Console.WriteLine("Sent: {0}", message);

            // Receive the TcpServer.response. 

            // Buffer to store the response bytes.
            data = new Byte[256];

            // String to store the response ASCII representation.
            String responseData = String.Empty;

            // Read the first batch of the TcpServer response bytes.
            Int32 bytes = stream.Read(data, 0, data.Length);
            responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
            Console.WriteLine("Received: {0}", responseData);

            // Close everything.
            stream.Close();
            client.Close();
        }
        catch (ArgumentNullException e)
        {
            Console.WriteLine("ArgumentNullException: {0}", e);
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: {0}", e);
        }

        Console.WriteLine("\n Press Enter to continue...");
        Console.Read();
    }

这是我的服务器:

代码语言:javascript
运行
复制
            // Listen loop.
            while(true)
            {
                using (TcpClient tcpClient = myListener.AcceptTcpClient())
                {
                    Console.WriteLine("[Server] Acceptam client.");
                    using (NetworkStream networkStream = tcpClient.GetStream())
                    {
                        // Buffer for reading data
                        Byte[] bytes = new Byte[1024];
                        var data = new List<byte>();

                        int length;

                        while ((length = networkStream.Read(bytes, 0, bytes.Length)) != 0)
                        {
                            var copy = new byte[length];
                            Array.Copy(bytes, 0, copy, 0, length);
                            data.AddRange(copy);
                        }

                        // Incercam sa vedem ce doreste clientul.
                        string msg = Encoding.ASCII.GetString(data[0], 0, length);
                        if(msg.StartsWith("SendFile"))
                        {
                            using (Stream stream = new FileStream(@"C:\test.mp3", FileMode.Create, FileAccess.ReadWrite))
                            {
                                BinaryFormatter binaryFormatter = new BinaryFormatter();
                                networkStream.Position = 4;
                                binaryFormatter.Serialize(networkStream, data.ToArray());
                            }
                        }
                    }
                }
            }

我在这里尝试做的是:-我想让客户端发送一条消息..比如"SaveFile“&在这个字符串之后作为文件数据。-服务器应该读取客户端消息,并在对文件执行某些操作之前,根据客户端发送字符串来处理内容。

我想我不知道该怎么做。

我可以有一个关于如何发送/接收和从文件的乞求中读取某些字符串的示例吗?我如何将它们放在字节数组中,以及如何读取它...这是相当压倒性的..

PS:当前的服务器代码正在读取数据,并且可以像我编写代码一样写入数据,而不会丢失任何包。但他也在写我在转换文件字节之前发送的额外数据包。

EN

回答 1

Stack Overflow用户

发布于 2014-11-14 15:01:42

networkStream.Position = 4;是不合法的,因为NetworkStream是不可搜索的。

我建议您不要将文本和二进制数据混合在一起,因为这会使应用程序协议变得复杂。但是如果你真的想这样做,你应该使用BinaryWriterBinaryReader,因为它可以将字符串写到流中,然后可以在不消耗字符串后面的字节的情况下读取该流。

然后你可以做这样的事情..。

在客户端:

代码语言:javascript
运行
复制
BinaryWriter writer = new BinaryWriter(networkStream);

writer.Write("SendFile");
writer.Write(fileData.Length);
writer.Write(fileData);

在服务器中:

代码语言:javascript
运行
复制
BinaryReader reader = new BinaryReader(networkStream);

switch (reader.ReadString())
{
    case "SendFile":
    {
        int length = reader.ReadInt32();
        byte[] fileData = reader.ReadBytes(length);
        // ... then do whatever with fileData, like write to a file
        break;
    }
}

长度计数字符串的BinaryWriter/Reader实现是非标准的,因此,如果您希望使用此技术与任何其他非.NET代码进行交互,则会更加复杂,因为您必须自己复制/重新实现非标准的长度计数逻辑。

更好的方法是将命令编码为固定长度的数据,例如8位、16位或32位的值,它只是指定命令的某个整数。然后,您可以在代码中将命令作为enum类型列出,将I/O转换为网络流,这将更加可移植,更易于在非.NET平台上实现。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26923803

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档